Skip to content

Commit 92cbfa4

Browse files
committed
Optimization
Program has been optimized by many orders of magnitude.
1 parent 528343e commit 92cbfa4

1 file changed

Lines changed: 51 additions & 15 deletions

File tree

src/main/Main.java

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package main;
22

3-
import java.io.BufferedInputStream;
4-
import java.io.BufferedOutputStream;
53
import java.io.BufferedReader;
64
import java.io.InputStream;
75
import java.io.InputStreamReader;
@@ -47,8 +45,7 @@ public class Main
4745
private static final MessageDigest OUT_DIGEST = DIGEST_SUPPLIER.get();
4846
private static final MessageDigest IN_DIGEST = DIGEST_SUPPLIER.get();
4947
static final short KB = 1024;
50-
static final int MB = KB * 1024;
51-
static final int GB = MB * 1024;
48+
static final int MB = KB * 1024, GB = MB * 1024, MAX_BUFFER = MB * 20;
5249
static
5350
{
5451
final OptionGroup group = new OptionGroup();
@@ -63,6 +60,7 @@ public class Main
6360
public static void main(String[] args)
6461
{
6562
final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
63+
final long startTime;
6664
try
6765
{
6866
final CommandLine commandLine = PARSER.parse(OPTIONS, args);
@@ -79,6 +77,7 @@ public static void main(String[] args)
7977
if (Boolean.parseBoolean(reader.readLine()))
8078
{
8179
System.out.println("Beginning operation...");
80+
startTime = System.currentTimeMillis();
8281
final ObjectInputStream objectInputStream = new ObjectInputStream(Files.newInputStream(inputPath));
8382
final String outputFilename = (String) objectInputStream.readObject();
8483
final long totalSize = objectInputStream.readLong(), chunkSize = objectInputStream.readLong();
@@ -89,12 +88,12 @@ public static void main(String[] args)
8988
System.out.println("Thus there should be " + calculatedChunks + " chunks.");
9089
if (calculatedChunks != listedChunks)
9190
System.err.println("WARNING! Expected " + calculatedChunks + " chunks but got " + listedChunks + " listed chunks!");
92-
try (final OutputStream outputStream = new DigestOutputStream(new BufferedOutputStream(Files.newOutputStream(Paths.get(outputPath.toString(), outputFilename))), OUT_DIGEST))
91+
try (final OutputStream outputStream = new DigestOutputStream(Files.newOutputStream(Paths.get(outputPath.toString(), outputFilename)), OUT_DIGEST))
9392
{
9493
for (int i = 1; i < listedChunks + 1; i++)
9594
{
9695
System.out.println("Reading chunk #" + i + '/' + listedChunks + "...");
97-
final Path currentPath = Paths.get(inputPath.getParent().toString(), outputFilename + '.' + (i - 1) + ".part");
96+
final Path currentPath = Paths.get(inputPath.getParent().toString(), outputFilename + '.' + i + ".part");
9897
final long currentChunkSize = Files.size(currentPath), desiredSize = i < listedChunks + 1 ? chunkSize : totalSize - chunkSize * i;
9998
if (desiredSize != chunkSize)
10099
{
@@ -103,10 +102,17 @@ public static void main(String[] args)
103102
if (!Boolean.parseBoolean(reader.readLine()))
104103
System.exit(0);
105104
}
106-
try (final InputStream inputStream = new DigestInputStream(new BufferedInputStream(Files.newInputStream(currentPath)), IN_DIGEST))
105+
try (final InputStream inputStream = new DigestInputStream(Files.newInputStream(currentPath), IN_DIGEST))
107106
{
108-
while (inputStream.available() > 0)
109-
outputStream.write(inputStream.read());
107+
long size = Files.size(currentPath);
108+
while (size > 0)
109+
{
110+
final int bufferSize = (int) Math.min(MAX_BUFFER, size);
111+
final byte[] buffer = new byte[bufferSize];
112+
inputStream.read(buffer);
113+
outputStream.write(buffer);
114+
size -= bufferSize;
115+
}
110116
outputStream.flush();
111117
}
112118
final String realChecksum = bytesToHex(IN_DIGEST.digest()), savedChecksum = (String) objectInputStream.readObject();
@@ -124,6 +130,7 @@ public static void main(String[] args)
124130
System.err.println("WARNING! Final file checksum does not match! Expected " + expectedChecksum + " but got " + realChecksum + '!');
125131
}
126132
System.out.println("Done!");
133+
System.out.println(timeFromMillis(System.currentTimeMillis() - startTime));
127134
}
128135
else
129136
cancel();
@@ -142,36 +149,45 @@ public static void main(String[] args)
142149
if (Boolean.parseBoolean(reader.readLine()))
143150
{
144151
System.out.println("Beginning operation...");
152+
startTime = System.currentTimeMillis();
145153
final ObjectOutputStream objectOutputStream = new ObjectOutputStream(Files.newOutputStream(Paths.get(outputPath.toString(), inputPath.getFileName() + ".sum")));
146154
long processed = 0;
147155
objectOutputStream.writeObject(inputPath.getFileName().toString());
148156
objectOutputStream.writeLong(totalSize);
149157
objectOutputStream.writeLong(chunkSize);
150158
objectOutputStream.writeInt(totalChunks);
151-
try (final InputStream inputStream = new DigestInputStream(new BufferedInputStream(Files.newInputStream(inputPath)), IN_DIGEST))
159+
try (final InputStream inputStream = new DigestInputStream(Files.newInputStream(inputPath), IN_DIGEST))
152160
{
153-
int chunkIndex = 0;
161+
int chunkIndex = 1;
154162
while (inputStream.available() > 0)
155163
{
156164
final Path currentChunkPath = Paths.get(outputPath.toString(), inputPath.getFileName().toString() + '.' + chunkIndex + ".part");
157-
try (final OutputStream outputStream = new DigestOutputStream(new BufferedOutputStream(Files.newOutputStream(currentChunkPath)), OUT_DIGEST))
165+
try (final OutputStream outputStream = new DigestOutputStream(Files.newOutputStream(currentChunkPath), OUT_DIGEST))
158166
{
159167
final long maxAlloc = Math.min(chunkSize, totalSize - processed);
160-
for (long i = 0; i < maxAlloc; i++)
161-
outputStream.write(inputStream.read());
168+
long written = 0;
169+
while (written < maxAlloc)
170+
{
171+
final int bufferSize = (int) Math.min(MAX_BUFFER, maxAlloc);
172+
final byte[] buffer = new byte[bufferSize];
173+
inputStream.read(buffer);
174+
outputStream.write(buffer);
175+
written += bufferSize;
176+
}
162177

163178
outputStream.flush();
164179
processed += maxAlloc;
165180
objectOutputStream.writeObject(bytesToHex(IN_DIGEST.digest()));
166181
objectOutputStream.flush();
167-
System.out.println("Wrote: " + currentChunkPath + " at " + maxAlloc + " bytes.");
182+
System.out.println(String.format("(#%s/%s) Wrote: %s at %s bytes.", chunkIndex, totalChunks, currentChunkPath, maxAlloc));
168183
}
169184
chunkIndex++;
170185
}
171186
objectOutputStream.writeObject(bytesToHex(OUT_DIGEST.digest()));
172187
objectOutputStream.flush();
173188
}
174189
System.out.println("Done!");
190+
System.out.println(timeFromMillis(System.currentTimeMillis() - startTime));
175191
}
176192
else
177193
cancel();
@@ -216,6 +232,26 @@ private static int magnitudeFromName(String name)
216232
}
217233
}
218234

235+
private static String timeFromMillis(long timeIn)
236+
{
237+
final StringBuilder builder = new StringBuilder("Operation took: ");
238+
final long secondMillis = 1000, minuteMillis = 60 * secondMillis, hourMillis = 60 * minuteMillis;
239+
long time = timeIn;
240+
if (time >= hourMillis)
241+
{
242+
builder.append(Math.floorDiv(time, hourMillis)).append(" hour(s) ");
243+
time %= hourMillis;
244+
}
245+
if (time >= minuteMillis)
246+
{
247+
builder.append(Math.floorDiv(time, minuteMillis)).append(" minute(s) ");
248+
time %= minuteMillis;
249+
}
250+
if (time >= secondMillis)
251+
builder.append((double) time / secondMillis).append(" second(s)");
252+
return builder.append('.').toString();
253+
}
254+
219255
private static void cancel()
220256
{
221257
System.out.println("Cancelling execution...");

0 commit comments

Comments
 (0)