Skip to content

Instantly share code, notes, and snippets.

@kawasima
Created March 6, 2015 08:21
Show Gist options
  • Save kawasima/db70b9e27263bfafa6b6 to your computer and use it in GitHub Desktop.
Save kawasima/db70b9e27263bfafa6b6 to your computer and use it in GitHub Desktop.
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import static java.lang.System.out;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.OptionalDouble;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
/**
*
* @author kawasima
*/
public class TestCopyPerf {
public static final int PAGE_SIZE = 1024 * 4;
public static final long FILE_SIZE = PAGE_SIZE * 1000L * 50L;
public static final String FILE_NAME = "test.dat";
public static final byte[] BLANK_PAGE = new byte[PAGE_SIZE];
public static void main(final String[] arg) throws Exception
{
preallocateTestFile(FILE_NAME);
System.gc();
TimeUnit.SECONDS.sleep(5L);
for (final PerfTestCase testCase : testCases) {
OptionalDouble avg = IntStream
.range(0, 5)
.mapToDouble(i-> {
long testDurationMs = testCase.test(FILE_NAME);
out.format("%s\t%,d bytes/sec\n",
testCase.getName(), (FILE_SIZE * 1000L) / testDurationMs);
return (double) testDurationMs;
})
.average();
out.format(" total average duration = %.3f msec\n", avg.orElse(0));
}
deleteFile(FILE_NAME);
}
private static void preallocateTestFile(final String fileName)
throws Exception
{
try (RandomAccessFile file = new RandomAccessFile(fileName, "rw")) {
for (long i = 0; i < FILE_SIZE; i += PAGE_SIZE) {
file.write(BLANK_PAGE, 0, PAGE_SIZE);
}
}
}
private static void deleteFile(final String testFileName) throws Exception
{
File file = new File(testFileName);
if (!file.delete())
{
out.println("Failed to delete test file=" + testFileName);
out.println("Windows does not allow mapped files to be deleted.");
}
}
public abstract static class PerfTestCase
{
private final String name;
public PerfTestCase(final String name) {
this.name = name;
}
public String getName() {
return name;
}
public long test(final String fileName)
{
long start = System.currentTimeMillis();
try {
testCopy(fileName);
} catch (Exception ex) {
ex.printStackTrace();
}
return System.currentTimeMillis() - start;
}
public abstract void testCopy(final String fileName) throws Exception;
}
private static PerfTestCase[] testCases = {
new PerfTestCase("BufferedStreamFile") {
@Override
public void testCopy(final String fileName) throws Exception {
Path tmp = Files.createTempFile(Paths.get("target"), "copytest", "tmp");
try (InputStream in = new BufferedInputStream(new FileInputStream(fileName));
OutputStream out = new BufferedOutputStream(new FileOutputStream(tmp.toString()))) {
for (;;) {
int b = in.read();
if (b < 0) break;
out.write(b);
}
} finally {
Files.deleteIfExists(tmp);
}
}
},
new PerfTestCase("BufferedChannelFile") {
@Override
public void testCopy(final String fileName) throws Exception {
Path tmp = Files.createTempFile(Paths.get("target"), "copytest", "tmp");
try (FileInputStream fis = new FileInputStream(fileName);
FileOutputStream fos = new FileOutputStream(tmp.toString());
FileChannel in = fis.getChannel();
FileChannel out = fos.getChannel()) {
final long size = in.size();
long pos = 0;
long count;
while (pos < size) {
final long remain = size - pos;
count = remain > PAGE_SIZE ? PAGE_SIZE : remain;
final long bytesCopied = out.transferFrom(in, pos, count);
if (bytesCopied == 0) {
break;
}
pos += bytesCopied;
}
} finally {
Files.deleteIfExists(tmp);
}
}
},
new PerfTestCase("Files copy") {
@Override
public void testCopy(String fileName) throws Exception {
Path tmp = Files.createTempFile(Paths.get("target"), "copytest", "tmp");
try {
Files.copy(Paths.get(fileName), tmp, StandardCopyOption.REPLACE_EXISTING);
} finally {
Files.deleteIfExists(tmp);
}
}
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment