As this seems crucial for log performance, I made a test to see for myself what's really the best way to write a log. It tests various forced sequential write methods, with growing and preallocated file. Using direct buffers doesn't seem to have any effect over plain RandomAccessFile.write(byte[]).
Following results are from my Athlon XP 1700+ Windows XP Professional machine,
with IDE disk that can dish out unsynced writes at 40MB/s, running JDK1.5 RC.
It proves Mike's point about "rws" being best on preallocated files on Windows.
That is, it can write 10MB/s in 4228 byte chunks, that is about 2490 chunks per
sec.
So if you want to get 10000 transactions/sec, you will have to combine logs and
write them in one chunk. I think that's exactly what Derby does. So we're all
good ;)
It also shows that sync() / force() are thing to avoid at all costs on Windows
;)
Can anyone run the test on another OS? I've attached the source file for the
tests.
(warning: 10000 records test ran for 30minutes ;-) You can decrease the chunk
count)
---------------------------------------------
1. System info:
---------------------------------------------
OS Platform: Windows XP/x86/5.1
Java spec: Java Platform API Specification version 1.5 from Sun Microsystems
Inc.
Java VM: Java HotSpot(TM) Client VM version 1.5.0-rc-b63 from Sun
Microsystems Inc.
Java home: C:\java\jdk1.5.0\jre
Test file: C:\Documents and Settings\hlavac\iotest\test.bin
Test file exists, deleting...
---------------------------------------------------------------------
2. Testing growing file using RandomAccessFile "rw" + .getFD().sync()
---------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 283527 ms
Writes per second: 35.27 writes/s
Time per chunk: 28.353 ms
Write bandwidth: 144.0KB/s
---------------------------------------------------------------------------
3. Testing preallocated file using RandomAccessFile "rw" + .getFD().sync()
---------------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 276988 ms
Writes per second: 36.103 writes/s
Time per chunk: 27.699 ms
Write bandwidth: 148.0KB/s
---------------------------------------------------------------------
4. Testing growing file using RandomAccessFile "rws"
---------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 9173 ms
Writes per second: 1090.156 writes/s
Time per chunk: 0.917 ms
Write bandwidth: 4.0MB/s
---------------------------------------------------------------------
5. Testing preallocated file using RandomAccessFile "rws"
---------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 4016 ms
Writes per second: 2490.04 writes/s
Time per chunk: 0.402 ms
Write bandwidth: 10.0MB/s
---------------------------------------------------------------------
6. Testing growing file using RandomAccessFile "rwd"
---------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 10264 ms
Writes per second: 974.279 writes/s
Time per chunk: 1.026 ms
Write bandwidth: 3.0MB/s
---------------------------------------------------------------------
7. Testing preallocated file using RandomAccessFile "rwd"
---------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 5598 ms
Writes per second: 1786.352 writes/s
Time per chunk: 0.56 ms
Write bandwidth: 7.0MB/s
------------------------------------------------------------------------------
8. Testing growing file using direct buffer + FileChannel "rw" + force(true)
------------------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 281445 ms
Writes per second: 35.531 writes/s
Time per chunk: 28.144 ms
Write bandwidth: 144.0KB/s
-----------------------------------------------------------------------------------
9. Testing preallocated file using direct buffer + FileChannel "rw" +
force(true)
-----------------------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 276638 ms
Writes per second: 36.148 writes/s
Time per chunk: 27.664 ms
Write bandwidth: 148.0KB/s
------------------------------------------------------------------------------
10. Testing growing file using direct buffer + FileChannel "rw" + force(false)
------------------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 283908 ms
Writes per second: 35.223 writes/s
Time per chunk: 28.391 ms
Write bandwidth: 144.0KB/s
------------------------------------------------------------------------------
11. Testing preallocated file using direct buffer + FileChannel "rw" +
force(false)
------------------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 277960 ms
Writes per second: 35.976 writes/s
Time per chunk: 27.796 ms
Write bandwidth: 144.0KB/s
------------------------------------------------------------------------------
12. Testing growing file using direct buffer + FileChannel "rws"
------------------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 8733 ms
Writes per second: 1145.082 writes/s
Time per chunk: 0.873 ms
Write bandwidth: 4.0MB/s
------------------------------------------------------------------------------
13. Testing preallocated file using direct buffer + FileChannel "rws"
------------------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 3805 ms
Writes per second: 2628.121 writes/s
Time per chunk: 0.381 ms
Write bandwidth: 10.0MB/s
------------------------------------------------------------------------------
14. Testing growing file using direct buffer + FileChannel "rwd"
------------------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 10595 ms
Writes per second: 943.841 writes/s
Time per chunk: 1.06 ms
Write bandwidth: 3.0MB/s
------------------------------------------------------------------------------
15. Testing preallocated file using direct buffer + FileChannel "rwd"
------------------------------------------------------------------------------
Chunk size: 4228 bytes
Count: 10000
Total time: 5508 ms
Writes per second: 1815.541 writes/s
Time per chunk: 0.551 ms
Write bandwidth: 7.0MB/s
/*
* Main.java
*
* Created on 4. z��� 2004, 10:13
*/
package iotest;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
/**
*
* @author hlavac
*/
public class Main {
public static void main(String[] args) {
// change these to play with chunk size/file length
int chunksize = 4228;
int chunks = 10000; // ~ 40MB
try {
File testfile = new File("test.bin").getCanonicalFile();
System.out.println("\n---------------------------------------------\n1. System
info:\n---------------------------------------------\n");
System.out.println("OS Platform:
"+System.getProperty("os.name","unknown")+"/"+System.getProperty("os.arch","unknown")+"/"+System.getProperty("os.version","unknown"));
System.out.println(" Java spec:
"+System.getProperty("java.specification.name","unknown")+" version
"+System.getProperty("java.specification.version","unknown")+" from
"+System.getProperty("java.specification.vendor","unknown"));
System.out.println(" Java VM:
"+System.getProperty("java.vm.name","unknown")+" version
"+System.getProperty("java.vm.version","unknown")+" from
"+System.getProperty("java.vm.vendor","unknown"));
System.out.println(" Java home:
"+System.getProperty("java.home","unknown"));
System.out.println(" Test file: "+testfile);
if (testfile.exists()) {
System.out.println("\nTest file exists, deleting...");
testfile.delete();
}
long toalsize = chunksize*chunks;
byte[] buffer = new byte[chunksize];
buffer[0]='<';
buffer[chunksize-1]='>';
for (int j=1;j<chunksize-1; j++) buffer[j]=' ';
try {
System.out.println(
"\n---------------------------------------------------------------------"+
"\n2. Testing growing file using
RandomAccessFile \"rw\" + .getFD().sync()"+
"\n---------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rw");
try {
raf.seek(0L);
FileDescriptor fd = raf.getFD();
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
raf.write(buffer);
fd.sync();
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+" ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
Thread.sleep(4000); // zzz...
try {
System.out.println(
"\n---------------------------------------------------------------------------"+
"\n3. Testing preallocated file using
RandomAccessFile \"rw\" + .getFD().sync()"+
"\n---------------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rw");
try {
raf.seek(0L);
FileDescriptor fd = raf.getFD();
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
raf.write(buffer);
fd.sync();
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+" ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
testfile.delete();
Thread.sleep(4000); // zzz...
try {
System.out.println(
"\n---------------------------------------------------------------------"+
"\n4. Testing growing file using
RandomAccessFile \"rws\""+
"\n---------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rws");
try {
raf.seek(0L);
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
raf.write(buffer);
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+" ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
Thread.sleep(4000); // zzz...
try {
System.out.println(
"\n---------------------------------------------------------------------"+
"\n5. Testing preallocated file using
RandomAccessFile \"rws\""+
"\n---------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rws");
try {
raf.seek(0L);
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
raf.write(buffer);
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+" ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
testfile.delete();
Thread.sleep(4000); // zzz...
try {
System.out.println(
"\n---------------------------------------------------------------------"+
"\n6. Testing growing file using
RandomAccessFile \"rwd\""+
"\n---------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rwd");
try {
raf.seek(0L);
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
raf.write(buffer);
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+" ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
Thread.sleep(4000); // zzz...
try {
System.out.println(
"\n---------------------------------------------------------------------"+
"\n7. Testing preallocated file using
RandomAccessFile \"rwd\""+
"\n---------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rwd");
try {
raf.seek(0L);
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
raf.write(buffer);
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+" ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
testfile.delete();
Thread.sleep(4000); // zzz...
ByteBuffer directbuf = ByteBuffer.allocateDirect(chunksize);
directbuf.clear();
directbuf.put((byte)'<');
for (int i=1; i<chunksize-1;i++) {
directbuf.put((byte)' ');
}
directbuf.put((byte)'>');
try {
System.out.println(
"\n------------------------------------------------------------------------------"+
"\n8. Testing growing file using direct
buffer + FileChannel \"rw\" + force(true)" +
"\n------------------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rw");
try {
FileChannel fch = raf.getChannel();
try {
fch.position(0L);
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
directbuf.clear();
fch.write(directbuf);
fch.force(true);
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+"
ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
fch.close();
}
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
Thread.sleep(4000); // zzz...
try {
System.out.println(
"\n-----------------------------------------------------------------------------------"+
"\n9. Testing preallocated file using
direct buffer + FileChannel \"rw\" + force(true)" +
"\n-----------------------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rw");
try {
FileChannel fch = raf.getChannel();
try {
fch.position(0L);
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
directbuf.clear();
fch.write(directbuf);
fch.force(true);
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+"
ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
fch.close();
}
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
testfile.delete();
Thread.sleep(4000); // zzz...
try {
System.out.println(
"\n------------------------------------------------------------------------------"+
"\n10. Testing growing file using direct
buffer + FileChannel \"rw\" + force(false)" +
"\n------------------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rw");
try {
FileChannel fch = raf.getChannel();
try {
fch.position(0L);
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
directbuf.clear();
fch.write(directbuf);
fch.force(false);
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+"
ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
fch.close();
}
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
Thread.sleep(4000); // zzz...
try {
System.out.println(
"\n------------------------------------------------------------------------------"+
"\n11. Testing preallocated file using
direct buffer + FileChannel \"rw\" + force(false)" +
"\n------------------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rw");
try {
FileChannel fch = raf.getChannel();
try {
fch.position(0L);
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
directbuf.clear();
fch.write(directbuf);
fch.force(false);
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+"
ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
fch.close();
}
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
testfile.delete();
Thread.sleep(4000); // zzz...
try {
System.out.println(
"\n------------------------------------------------------------------------------"+
"\n12. Testing growing file using direct
buffer + FileChannel \"rws\""+
"\n------------------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rws");
try {
FileChannel fch = raf.getChannel();
try {
fch.position(0L);
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
directbuf.clear();
fch.write(directbuf);
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+"
ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
fch.close();
}
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
Thread.sleep(4000); // zzz...
try {
System.out.println(
"\n------------------------------------------------------------------------------"+
"\n13. Testing preallocated file using
direct buffer + FileChannel \"rws\"" +
"\n------------------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rws");
try {
FileChannel fch = raf.getChannel();
try {
fch.position(0L);
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
directbuf.clear();
fch.write(directbuf);
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+"
ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
fch.close();
}
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
testfile.delete();
Thread.sleep(4000); // zzz...
try {
System.out.println(
"\n------------------------------------------------------------------------------"+
"\n14. Testing growing file using direct
buffer + FileChannel \"rwd\""+
"\n------------------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rwd");
try {
FileChannel fch = raf.getChannel();
try {
fch.position(0L);
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
directbuf.clear();
fch.write(directbuf);
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+"
ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
fch.close();
}
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
Thread.sleep(4000); // zzz...
try {
System.out.println(
"\n------------------------------------------------------------------------------"+
"\n15. Testing preallocated file using
direct buffer + FileChannel \"rwd\"" +
"\n------------------------------------------------------------------------------");
RandomAccessFile raf = new RandomAccessFile(testfile,"rwd");
try {
FileChannel fch = raf.getChannel();
try {
fch.position(0L);
long starttime = System.currentTimeMillis();
for (int i=0; i<chunks; i++) {
directbuf.clear();
fch.write(directbuf);
}
long endtime = System.currentTimeMillis();
long totaltime = endtime-starttime;
double chunks_per_s = 1000.0*chunks/totaltime;
System.out.println(" Chunk size: "+chunksize+"
bytes");
System.out.println(" Count: "+chunks);
System.out.println(" Total time: "+totaltime+"
ms");
System.out.println("Writes per second:
"+round3(chunks_per_s)+" writes/s");
System.out.println(" Time per chunk:
"+round3((1000.0/chunks_per_s))+" ms");
System.out.println(" Write bandwidth:
"+kmg((long)chunks_per_s*chunksize)+"B/s");
} finally {
fch.close();
}
} finally {
raf.close();
}
} catch (Throwable t) {
System.out.println("\nFailed with exception:
"+t.toString()+"\n");
}
} catch (Throwable t) {
System.out.println("\nUnexpected exception:");
t.printStackTrace();
}
}
public static double round3(double what) {
return Math.round(1000.0*what)/1000.0;
}
public static final long KILO = 1024;
public static final long MEGA = 1024*1024;
public static final long GIGA = 1024*1024*1024;
public static String kmg(long bytes) {
if (bytes >= GIGA) {
return ""+round3(bytes/GIGA)+"G";
} else if (bytes >= MEGA) {
return ""+round3(bytes/MEGA)+"M";
} else if (bytes >= KILO) {
return ""+round3(bytes/KILO)+"K";
} else {
return ""+bytes;
}
}
}
signature.asc
Description: OpenPGP digital signature
