Last active
October 6, 2020 14:59
-
-
Save seraphy/c173e3d82afd1ad3f81c to your computer and use it in GitHub Desktop.
JavaのNIOのダイレクトバッファのベンチマーク。allocDirectのパフォーマンス比較およびネイティブメモリのコミットサイズの遷移の確認用、および、10MiBのファイル読み込みのパフォーマンス比較。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.seraphyware.jmhexample; | |
import java.io.IOException; | |
import java.nio.ByteBuffer; | |
import java.nio.ByteOrder; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import org.openjdk.jmh.annotations.Level; | |
import org.openjdk.jmh.annotations.Scope; | |
import org.openjdk.jmh.annotations.Setup; | |
import org.openjdk.jmh.annotations.State; | |
import org.openjdk.jmh.annotations.TearDown; | |
/** | |
* テスト中にスレッドごとベンチマークごとの状態を保持するインスタンス. | |
* | |
* @author seraphy | |
*/ | |
@State(Scope.Thread) | |
public abstract class AbstractFileBenchContext { | |
protected final ByteOrder byteOrder; | |
protected final int bufsiz; | |
private Path tempFile; | |
private ByteBuffer bufHeap; | |
private ByteBuffer bufDirect; | |
protected AbstractFileBenchContext(ByteOrder byteOrder, int bufsiz) { | |
this.byteOrder = byteOrder; | |
this.bufsiz = bufsiz; | |
} | |
/** | |
* データの初期化. | |
* Trialの場合、スレッドごとベンチマークの開始ごとに一度呼び出される.<br> | |
* (ウォームアップイテレーション、および計測イテレーション中には呼び出されない。) | |
* (Trialがデフォルト、そのほかにIteration, Invocationが指定可能.) | |
*/ | |
@Setup(Level.Trial) | |
public void setup() throws IOException { | |
// バッファの確保 (ヒープ) | |
byte[] data = new byte[bufsiz]; | |
bufHeap = ByteBuffer.wrap(data); | |
bufHeap.order(byteOrder); | |
// バッファの確保 (ダイレクト) | |
bufDirect = ByteBuffer.allocateDirect(data.length); | |
bufDirect.order(byteOrder); | |
// テストデータファイルの作成 | |
tempFile = initTempFile(); | |
} | |
protected abstract Path initTempFile() throws IOException; | |
/** | |
* スレッドごとベンチマーク終了ごとに呼び出される. | |
*/ | |
@TearDown | |
public void teardown() { | |
try { | |
//System.out.println("★delete tempFile=" + tempFile); | |
Files.deleteIfExists(tempFile); | |
} catch (Exception ex) { | |
ex.printStackTrace(); | |
} | |
} | |
public Path getTempFile() { | |
return tempFile; | |
} | |
public abstract void verify(Object actual); | |
public ByteBuffer getBufDirect() { | |
return bufDirect; | |
} | |
public ByteBuffer getBufHeap() { | |
return bufHeap; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.seraphyware.jmhexample; | |
import java.nio.ByteBuffer; | |
import org.openjdk.jmh.annotations.Benchmark; | |
import org.openjdk.jmh.annotations.Level; | |
import org.openjdk.jmh.annotations.Scope; | |
import org.openjdk.jmh.annotations.Setup; | |
import org.openjdk.jmh.annotations.State; | |
import org.openjdk.jmh.runner.Runner; | |
import org.openjdk.jmh.runner.RunnerException; | |
import org.openjdk.jmh.runner.options.Options; | |
import org.openjdk.jmh.runner.options.OptionsBuilder; | |
import org.openjdk.jmh.runner.options.TimeValue; | |
public class BufferAllocBenchmark { | |
@State(Scope.Thread) | |
public static class BufferAllocContext { | |
private ByteBuffer buf; | |
@Setup(Level.Trial) | |
public void setup() { | |
} | |
public void setByteBuffer(ByteBuffer buf) { | |
this.buf = buf; | |
} | |
public ByteBuffer getButeBuffer() { | |
return this.buf; | |
} | |
} | |
@Benchmark | |
public void testAllocDirect8(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocateDirect(8 * 1024)); | |
} | |
@Benchmark | |
public void testAllocHeap8(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocate(8 * 1024)); | |
} | |
@Benchmark | |
public void testAllocDirect16(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocateDirect(16 * 1024)); | |
} | |
@Benchmark | |
public void testAllocHeap16(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocate(16 * 1024)); | |
} | |
@Benchmark | |
public void testAllocDirect32(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocateDirect(32 * 1024)); | |
} | |
@Benchmark | |
public void testAllocHeap32(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocate(32 * 1024)); | |
} | |
@Benchmark | |
public void testAllocDirect64(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocateDirect(64 * 1024)); | |
} | |
@Benchmark | |
public void testAllocHeap64(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocate(64 * 1024)); | |
} | |
@Benchmark | |
public void testAllocDirect128(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocateDirect(128 * 1024)); | |
} | |
@Benchmark | |
public void testAllocHeap128(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocate(128 * 1024)); | |
} | |
@Benchmark | |
public void testAllocDirect256(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocateDirect(256 * 1024)); | |
} | |
@Benchmark | |
public void testAllocHeap256(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocate(256 * 1024)); | |
} | |
@Benchmark | |
public void testAllocDirect512(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocateDirect(512 * 1024)); | |
} | |
@Benchmark | |
public void testAllocHeap512(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocate(512 * 1024)); | |
} | |
@Benchmark | |
public void testAllocDirect1024(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocateDirect(1024 * 1024)); | |
} | |
@Benchmark | |
public void testAllocHeap1024(BufferAllocContext ctx) { | |
ctx.setByteBuffer(ByteBuffer.allocate(1024 * 1024)); | |
} | |
/** | |
* IDEから実行する場合は、 | |
* まず先にmvn package等を実行してサポートファイル類を生成しておく必要がある. | |
* (少なくともクラスまたはメソッドのシグネチャを変更追加するたびにmvnでビルドする必要がある。) | |
* その後、IDEから、このメイン関数を呼び出すことができるようになる. | |
* @param args | |
* @throws RunnerException | |
*/ | |
public static void main(String[] args) throws RunnerException { | |
Options opt = new OptionsBuilder() | |
// 実行すべきベンチマークが定義された"クラス名.メソッド名"を正規表現で指定 | |
.include(BufferAllocBenchmark.class.getSimpleName()) | |
// ウォームアップイテレーション数 "-wi"オプションに相当 | |
.warmupIterations(10) | |
// イテレーション数 "-i"オプションに相当 | |
.measurementIterations(50) | |
// フォーク数 "-f"オプションに相当 | |
.forks(1) | |
// 1回のテストメソッド実行時間 "-r"オプションに相当 | |
.measurementTime(TimeValue.seconds(1)) | |
// 同時実行スレッド数 (1測定毎のスレッド数 (サンプル数が増える)) | |
// .threads(Math.max(1, Runtime.getRuntime().availableProcessors() - 1)) | |
// 測定するモード = スループット | |
//.timeUnit(TimeUnit.MICROSECONDS) | |
//.mode(Mode.SampleTime) | |
.build(); | |
new Runner(opt).run(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.seraphyware.jmhexample; | |
import java.nio.ByteBuffer; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class BufferAllocExample { | |
/** | |
* バイトバッファをallocする方法 | |
*/ | |
public enum ByteBufferAllocStrategy { | |
/** | |
* ヒープのByteBufferを構築する. | |
*/ | |
heap() { | |
@Override | |
public ByteBuffer alloc(int siz) { | |
return ByteBuffer.allocate(siz); | |
} | |
}, | |
/** | |
* ダイレクトのByteBufferを構築する. | |
*/ | |
direct() { | |
@Override | |
public ByteBuffer alloc(int siz) { | |
return ByteBuffer.allocateDirect(siz); | |
} | |
}; | |
public abstract ByteBuffer alloc(int siz); | |
} | |
/** | |
* エントリポイント. | |
* 第一引数にheapかdirectを指定する. | |
* @param args | |
* @throws Exception | |
*/ | |
public static void main(String... args) throws Exception { | |
ByteBufferAllocStrategy allocator = ByteBufferAllocStrategy | |
.valueOf(args[0]); | |
Runtime rt = Runtime.getRuntime(); | |
List<ByteBuffer> buffers = new ArrayList<>(); | |
// 10MiBの割り当てを10回繰り返す | |
for (int idx = 0; idx < 10; idx++) { | |
System.gc(); | |
System.out.println(rt.freeMemory() + "/" + rt.totalMemory()); | |
ByteBuffer buf = allocator.alloc(1024 * 1024 * 10); | |
buffers.add(buf); | |
} | |
// 100MiB割り当て後のヒープの残量 | |
System.gc(); | |
System.out.println(rt.freeMemory() + "/" + rt.totalMemory()); | |
// OSのコミットサイズ、プライベートワーキングセットのサイズを | |
// タスクマネージャで見られるように、アプリ終了前に一旦停止する。 | |
System.console().readLine(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.seraphyware.jmhexample; | |
import java.lang.reflect.Method; | |
import java.nio.ByteBuffer; | |
import java.util.function.IntFunction; | |
import java.util.stream.IntStream; | |
public class BufferStressAndCleanupExample { | |
/** | |
* 最新のバイトバッファを保持するスレッドローカル | |
*/ | |
public static ThreadLocal<ByteBuffer> lastBufTLS = new ThreadLocal<>();; | |
/** | |
* バイトバッファをallocする方法 | |
*/ | |
public enum ByteBufferAllocStrategy { | |
/** | |
* ヒープのByteBufferを構築する. | |
*/ | |
heap() { | |
@Override | |
public ByteBuffer alloc(int siz) { | |
return ByteBuffer.allocate(siz); | |
} | |
}, | |
/** | |
* ダイレクトのByteBufferを構築する. | |
*/ | |
direct() { | |
@Override | |
public ByteBuffer alloc(int siz) { | |
return ByteBuffer.allocateDirect(siz); | |
} | |
}; | |
public abstract ByteBuffer alloc(int siz); | |
} | |
/** | |
* バイトバッファの破棄方法. | |
*/ | |
public enum ByteBufferDeallocStrategy { | |
/** | |
* 何もしない.システムにお任せ. | |
*/ | |
none() { | |
@Override | |
public void dealloc(ByteBuffer buf) { | |
} | |
}, | |
/** | |
* 明示的にgcを呼び出す. | |
*/ | |
gc() { | |
@Override | |
public void dealloc(ByteBuffer buf) { | |
System.gc(); | |
} | |
}, | |
/** | |
* 明示的にcleanerを呼び出す. | |
*/ | |
cleaner() { | |
@Override | |
public void dealloc(ByteBuffer buf) { | |
if (buf != null && buf.isDirect()) { | |
destroyDirectByteBuffer(buf); | |
} | |
} | |
}; | |
public abstract void dealloc(ByteBuffer buf); | |
} | |
/** | |
* エントリポイント | |
* @param args | |
* @throws Exception | |
*/ | |
public static void main(String... args) throws Exception { | |
ByteBufferAllocStrategy allocator = ByteBufferAllocStrategy.valueOf(args[0]); | |
ByteBufferDeallocStrategy deallocator; | |
if (args.length > 1) { | |
deallocator = ByteBufferDeallocStrategy.valueOf(args[1]); | |
} else { | |
deallocator = ByteBufferDeallocStrategy.none; | |
} | |
int mxthread = (args.length > 2) ? Integer.parseInt(args[2]) : 2; | |
// 10MiBの割り当てを永久に繰り返すジョブ | |
Runnable job = () -> { | |
for (;;) { | |
try { | |
// ByteBufferの構築 | |
ByteBuffer buf = allocator.alloc(10 * 1024 * 1024); // 10MiB | |
// ByteBufferの破棄 | |
deallocator.dealloc(lastBufTLS.get()); | |
// 最後に確保したByteBufferの保存 | |
lastBufTLS.set(buf); | |
} catch (Exception ex) { | |
throw new RuntimeException(ex); | |
} | |
} | |
}; | |
IntFunction<Thread> makeThread = (idx) -> { | |
Thread t = new Thread(job); | |
t.setDaemon(false); | |
t.setName("bufferStress:" + idx); | |
return t; | |
}; | |
IntStream.range(0, mxthread) | |
.mapToObj(makeThread) | |
.forEach(Thread::start); | |
} | |
/** | |
* ダイレクトバッファを早期に開放する. | |
* (Hadoopのソースコードから引用.) | |
* | |
* DirectByteBuffers are garbage collected by using a phantom reference and a | |
* reference queue. Every once a while, the JVM checks the reference queue and | |
* cleans the DirectByteBuffers. However, as this doesn't happen | |
* immediately after discarding all references to a DirectByteBuffer, it's | |
* easy to OutOfMemoryError yourself using DirectByteBuffers. This function | |
* explicitly calls the Cleaner method of a DirectByteBuffer. | |
* | |
* @see https://hbase.apache.org/0.94/apidocs/src-html/org/apache/hadoop/hbase/util/DirectMemoryUtils.html#line.80 | |
* @param toBeDestroyed | |
* The DirectByteBuffer that will be "cleaned". Utilizes reflection. | |
* | |
*/ | |
public static void destroyDirectByteBuffer(ByteBuffer toBeDestroyed) { | |
try { | |
Method cleanerMethod = toBeDestroyed.getClass().getMethod("cleaner"); | |
cleanerMethod.setAccessible(true); | |
Object cleaner = cleanerMethod.invoke(toBeDestroyed); | |
Method cleanMethod = cleaner.getClass().getMethod("clean"); | |
cleanMethod.setAccessible(true); | |
cleanMethod.invoke(cleaner); | |
} catch (Exception ex) { | |
throw new RuntimeException(ex); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.seraphyware.jmhexample; | |
import static java.nio.file.StandardOpenOption.*; | |
import java.io.BufferedInputStream; | |
import java.io.DataInputStream; | |
import java.io.FileInputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.nio.ByteBuffer; | |
import java.nio.ByteOrder; | |
import java.nio.channels.FileChannel; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import org.openjdk.jmh.annotations.Benchmark; | |
import org.openjdk.jmh.runner.Runner; | |
import org.openjdk.jmh.runner.RunnerException; | |
import org.openjdk.jmh.runner.options.Options; | |
import org.openjdk.jmh.runner.options.OptionsBuilder; | |
import org.openjdk.jmh.runner.options.TimeValue; | |
/** | |
* ファイルアクセスベンチマーク定義クラス(Double) | |
* | |
* @author seraphy | |
*/ | |
public class FileBufferAccessDoubleBenchmark { | |
/** | |
* テスト中にスレッドごとベンチマークごとの状態を保持するインスタンス. | |
* | |
* @author seraphy | |
*/ | |
protected static class BenchContextBase extends AbstractFileBenchContext { | |
public static final int reqSize = 1024 * 1024 * 10; // 10MiBytes | |
private double total; | |
protected BenchContextBase(ByteOrder byteOrder, int bufsiz) { | |
super(byteOrder, bufsiz); | |
} | |
/** | |
* テストデータファイルの作成 | |
* @throws IOException | |
*/ | |
@Override | |
protected Path initTempFile() throws IOException { | |
Path tempFile = Files.createTempFile("filebufferbench", ".tmp"); | |
//System.out.println("★create tempFile=" + tempFile); | |
ByteBuffer buf = ByteBuffer.allocate(bufsiz); | |
buf.order(byteOrder); | |
total = 0d; | |
int capacity = buf.capacity(); | |
long siz; | |
try (FileChannel channel = (FileChannel) Files | |
.newByteChannel(tempFile, CREATE, TRUNCATE_EXISTING, WRITE)) { | |
double idx = 0; | |
int mx = reqSize / capacity; | |
for (int loop = 0; loop < mx; loop++) { | |
buf.clear(); | |
while (buf.position() < capacity) { | |
buf.putDouble(idx); | |
total += idx; | |
idx += 1; | |
} | |
buf.flip(); | |
channel.write(buf); | |
} | |
siz = channel.size(); | |
} | |
if (reqSize != siz) { | |
throw new RuntimeException(); | |
} | |
//System.out.println("★total=" + total + "/size=" + siz); | |
return tempFile; | |
} | |
@Override | |
public void verify(Object actual) { | |
if ((Double) actual != total) { | |
throw new RuntimeException("actual=" + actual); | |
} | |
} | |
} | |
public static class BenchContextLE8k extends BenchContextBase { | |
public BenchContextLE8k() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 8); | |
} | |
} | |
public static class BenchContextBE8k extends BenchContextBase { | |
public BenchContextBE8k() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 8); | |
} | |
} | |
public static class BenchContextLE16 extends BenchContextBase { | |
public BenchContextLE16() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 16); | |
} | |
} | |
public static class BenchContextBE16 extends BenchContextBase { | |
public BenchContextBE16() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 16); | |
} | |
} | |
public static class BenchContextLE32 extends BenchContextBase { | |
public BenchContextLE32() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 32); | |
} | |
} | |
public static class BenchContextBE32 extends BenchContextBase { | |
public BenchContextBE32() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 32); | |
} | |
} | |
public static class BenchContextLE64 extends BenchContextBase { | |
public BenchContextLE64() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 64); | |
} | |
} | |
public static class BenchContextBE64 extends BenchContextBase { | |
public BenchContextBE64() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 64); | |
} | |
} | |
public static class BenchContextLE128 extends BenchContextBase { | |
public BenchContextLE128() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 128); | |
} | |
} | |
public static class BenchContextBE128 extends BenchContextBase { | |
public BenchContextBE128() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 128); | |
} | |
} | |
public static class BenchContextLE256 extends BenchContextBase { | |
public BenchContextLE256() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 256); | |
} | |
} | |
public static class BenchContextBE256 extends BenchContextBase { | |
public BenchContextBE256() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 256); | |
} | |
} | |
public static class BenchContextLE512 extends BenchContextBase { | |
public BenchContextLE512() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 512); | |
} | |
} | |
public static class BenchContextBE512 extends BenchContextBase { | |
public BenchContextBE512() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 512); | |
} | |
} | |
public static class BenchContextLE1m extends BenchContextBase { | |
public BenchContextLE1m() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 1024); | |
} | |
} | |
public static class BenchContextBE1m extends BenchContextBase { | |
public BenchContextBE1m() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 1024); | |
} | |
} | |
/** | |
* バイトバッファからdouble値を読み出すテスト | |
* @param buf | |
*/ | |
private static double runByteBuffer(FileChannel channel, ByteBuffer buf) | |
throws IOException { | |
double total = 0; | |
for (;;) { | |
buf.clear(); | |
int len = channel.read(buf); | |
if (len < 0) { | |
break; | |
} | |
buf.flip(); | |
int limit = buf.limit(); | |
while (buf.position() < limit) { | |
total += buf.getDouble(); | |
} | |
} | |
return total; | |
} | |
private static void doBench(BenchContextBase ctx, ByteBuffer buf) | |
throws IOException { | |
try (FileChannel channel = (FileChannel) Files.newByteChannel( | |
ctx.getTempFile(), READ)) { | |
ctx.verify(runByteBuffer(channel, buf)); | |
} | |
} | |
@Benchmark | |
public void testHeapBufferLE8k(BenchContextLE8k ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE8k(BenchContextLE8k ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE16(BenchContextLE16 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE16(BenchContextLE16 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE32(BenchContextLE32 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE32(BenchContextLE32 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE64(BenchContextLE64 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE64(BenchContextLE64 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE128(BenchContextLE128 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE128(BenchContextLE128 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE256(BenchContextLE256 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE256(BenchContextLE256 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE512(BenchContextLE512 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE512(BenchContextLE512 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE1m(BenchContextLE1m ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE1m(BenchContextLE1m ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE8k(BenchContextBE8k ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE8k(BenchContextBE8k ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE16(BenchContextBE16 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE16(BenchContextBE16 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE32(BenchContextBE32 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE32(BenchContextBE32 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE64(BenchContextBE64 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE64(BenchContextBE64 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE128(BenchContextBE128 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE128(BenchContextBE128 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE256(BenchContextBE256 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE256(BenchContextBE256 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE512(BenchContextBE512 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE512(BenchContextBE512 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE1m(BenchContextBE1m ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE1m(BenchContextBE1m ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
private static double readDoubles(InputStream is, int cnt) throws IOException { | |
double total = 0; | |
try (DataInputStream dis = new DataInputStream(is)) { | |
for (int idx = 0; idx < cnt; idx++) { | |
total += dis.readDouble(); | |
} | |
} | |
return total; | |
} | |
@Benchmark | |
public void testOldBufferedIO8k(BenchContextBE1m ctx) throws IOException { | |
double total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
new FileInputStream(ctx.getTempFile().toFile()))) { | |
total = readDoubles(bis, BenchContextBase.reqSize / 8); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedNIO8k(BenchContextBE1m ctx) throws IOException { | |
double total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
Files.newInputStream(ctx.getTempFile()))) { | |
total = readDoubles(bis, BenchContextBase.reqSize / 8); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedIO16(BenchContextBE1m ctx) throws IOException { | |
double total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
new FileInputStream(ctx.getTempFile().toFile()), 1024 * 16)) { | |
total = readDoubles(bis, BenchContextBase.reqSize / 8); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedNIO16(BenchContextBE1m ctx) throws IOException { | |
double total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
Files.newInputStream(ctx.getTempFile()), 1024 * 16)) { | |
total = readDoubles(bis, BenchContextBase.reqSize / 8); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedIO32(BenchContextBE1m ctx) throws IOException { | |
double total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
new FileInputStream(ctx.getTempFile().toFile()), 1024 * 32)) { | |
total = readDoubles(bis, BenchContextBase.reqSize / 8); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedNIO32(BenchContextBE1m ctx) throws IOException { | |
double total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
Files.newInputStream(ctx.getTempFile()), 1024 * 32)) { | |
total = readDoubles(bis, BenchContextBase.reqSize / 8); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedIO64(BenchContextBE1m ctx) throws IOException { | |
double total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
new FileInputStream(ctx.getTempFile().toFile()), 1024 * 64)) { | |
total = readDoubles(bis, BenchContextBase.reqSize / 8); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedNIO64(BenchContextBE1m ctx) throws IOException { | |
double total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
Files.newInputStream(ctx.getTempFile()), 1024 * 64)) { | |
total = readDoubles(bis, BenchContextBase.reqSize / 8); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedIO128k(BenchContextBE1m ctx) throws IOException { | |
double total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
new FileInputStream(ctx.getTempFile().toFile()), 1024 * 128)) { | |
total = readDoubles(bis, BenchContextBase.reqSize / 8); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedNIO128k(BenchContextBE1m ctx) throws IOException { | |
double total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
Files.newInputStream(ctx.getTempFile()), 1024 * 128)) { | |
total = readDoubles(bis, BenchContextBase.reqSize / 8); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldIO(BenchContextBE1m ctx) throws IOException { | |
double total; | |
try (InputStream bis = new FileInputStream( | |
ctx.getTempFile().toFile())) { | |
total = readDoubles(bis, BenchContextBase.reqSize / 8); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldNIO(BenchContextBE1m ctx) throws IOException { | |
double total; | |
try (InputStream bis = Files.newInputStream(ctx.getTempFile())) { | |
total = readDoubles(bis, BenchContextBase.reqSize / 8); | |
} | |
ctx.verify(total); | |
} | |
/** | |
* IDEから実行する場合は、 | |
* まず先にmvn package等を実行してサポートファイル類を生成しておく必要がある. | |
* (少なくともクラスまたはメソッドのシグネチャを変更追加するたびにmvnでビルドする必要がある。) | |
* その後、IDEから、このメイン関数を呼び出すことができるようになる. | |
* @param args | |
* @throws RunnerException | |
*/ | |
public static void main(String[] args) throws RunnerException { | |
Options opt = new OptionsBuilder() | |
// 実行すべきベンチマークが定義された"クラス名.メソッド名"を正規表現で指定 | |
.include(FileBufferAccessDoubleBenchmark.class.getSimpleName()) | |
// ウォームアップイテレーション数 "-wi"オプションに相当 | |
.warmupIterations(1) | |
// イテレーション数 "-i"オプションに相当 | |
.measurementIterations(1) | |
// フォーク数 "-f"オプションに相当 | |
.forks(1) | |
// 1回のテストメソッド実行時間 "-r"オプションに相当 | |
.measurementTime(TimeValue.seconds(1)) | |
// 同時実行スレッド数 (1測定毎のスレッド数 (サンプル数が増える)) | |
// .threads(Math.max(1, Runtime.getRuntime().availableProcessors() / 2)) | |
// 測定するモード = スループット | |
//.timeUnit(TimeUnit.MICROSECONDS) | |
//.mode(Mode.SampleTime) | |
.build(); | |
new Runner(opt).run(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.seraphyware.jmhexample; | |
import static java.nio.file.StandardOpenOption.*; | |
import java.io.BufferedInputStream; | |
import java.io.DataInputStream; | |
import java.io.FileInputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.nio.ByteBuffer; | |
import java.nio.ByteOrder; | |
import java.nio.channels.FileChannel; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import org.openjdk.jmh.annotations.Benchmark; | |
import org.openjdk.jmh.runner.Runner; | |
import org.openjdk.jmh.runner.RunnerException; | |
import org.openjdk.jmh.runner.options.Options; | |
import org.openjdk.jmh.runner.options.OptionsBuilder; | |
import org.openjdk.jmh.runner.options.TimeValue; | |
/** | |
* ファイルアクセスベンチマーク定義クラス(Int) | |
* | |
* @author seraphy | |
*/ | |
public class FileBufferAccessIntBenchmark { | |
public static class BenchContextBase extends AbstractFileBenchContext { | |
public static final int reqSize = 1024 * 1024 * 10; // 10MiBytes | |
private long total; | |
protected BenchContextBase(ByteOrder byteOrder, int bufsiz) { | |
super(byteOrder, bufsiz); | |
} | |
/** | |
* テストデータファイルの作成 | |
* @throws IOException | |
*/ | |
@Override | |
protected Path initTempFile() throws IOException { | |
Path tempFile = Files.createTempFile("filebufferbench", ".tmp"); | |
//System.out.println("★create tempFile=" + tempFile); | |
ByteBuffer buf = ByteBuffer.allocate(bufsiz); | |
buf.order(byteOrder); | |
total = 0; | |
int capacity = buf.capacity(); | |
long siz; | |
try (FileChannel channel = (FileChannel) Files | |
.newByteChannel(tempFile, CREATE, TRUNCATE_EXISTING, WRITE)) { | |
int idx = 0; | |
int mx = reqSize / capacity; | |
for (int loop = 0; loop < mx; loop++) { | |
buf.clear(); | |
while (buf.position() < capacity) { | |
buf.putInt(idx); | |
total += idx; | |
idx += 1; | |
} | |
buf.flip(); | |
channel.write(buf); | |
} | |
siz = channel.size(); | |
} | |
if (reqSize != siz) { | |
throw new RuntimeException(); | |
} | |
//System.out.println("★total=" + total + "/size=" + siz); | |
return tempFile; | |
} | |
@Override | |
public void verify(Object actual) { | |
if ((Long) actual != total) { | |
throw new RuntimeException("actual=" + actual); | |
} | |
} | |
} | |
public static class BenchContextLE8k extends BenchContextBase { | |
public BenchContextLE8k() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 8); | |
} | |
} | |
public static class BenchContextBE8k extends BenchContextBase { | |
public BenchContextBE8k() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 8); | |
} | |
} | |
public static class BenchContextLE16 extends BenchContextBase { | |
public BenchContextLE16() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 16); | |
} | |
} | |
public static class BenchContextBE16 extends BenchContextBase { | |
public BenchContextBE16() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 16); | |
} | |
} | |
public static class BenchContextLE32 extends BenchContextBase { | |
public BenchContextLE32() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 32); | |
} | |
} | |
public static class BenchContextBE32 extends BenchContextBase { | |
public BenchContextBE32() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 32); | |
} | |
} | |
public static class BenchContextLE64 extends BenchContextBase { | |
public BenchContextLE64() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 64); | |
} | |
} | |
public static class BenchContextBE64 extends BenchContextBase { | |
public BenchContextBE64() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 64); | |
} | |
} | |
public static class BenchContextLE128 extends BenchContextBase { | |
public BenchContextLE128() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 128); | |
} | |
} | |
public static class BenchContextBE128 extends BenchContextBase { | |
public BenchContextBE128() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 128); | |
} | |
} | |
public static class BenchContextLE256 extends BenchContextBase { | |
public BenchContextLE256() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 256); | |
} | |
} | |
public static class BenchContextBE256 extends BenchContextBase { | |
public BenchContextBE256() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 256); | |
} | |
} | |
public static class BenchContextLE512 extends BenchContextBase { | |
public BenchContextLE512() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 512); | |
} | |
} | |
public static class BenchContextBE512 extends BenchContextBase { | |
public BenchContextBE512() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 512); | |
} | |
} | |
public static class BenchContextLE1m extends BenchContextBase { | |
public BenchContextLE1m() { | |
super(ByteOrder.LITTLE_ENDIAN, 1024 * 1024); | |
} | |
} | |
public static class BenchContextBE1m extends BenchContextBase { | |
public BenchContextBE1m() { | |
super(ByteOrder.BIG_ENDIAN, 1024 * 1024); | |
} | |
} | |
/** | |
* バイトバッファからint値を読み出すテスト | |
* @param buf | |
*/ | |
private static long runByteBuffer(FileChannel channel, ByteBuffer buf) | |
throws IOException { | |
long total = 0; | |
for (;;) { | |
buf.clear(); | |
int len = channel.read(buf); | |
if (len < 0) { | |
break; | |
} | |
buf.flip(); | |
int limit = buf.limit(); | |
while (buf.position() < limit) { | |
total += buf.getInt(); | |
} | |
} | |
return total; | |
} | |
private static void doBench(AbstractFileBenchContext ctx, ByteBuffer buf) | |
throws IOException { | |
try (FileChannel channel = (FileChannel) Files.newByteChannel( | |
ctx.getTempFile(), READ)) { | |
ctx.verify(runByteBuffer(channel, buf)); | |
} | |
} | |
@Benchmark | |
public void testHeapBufferLE8k(BenchContextLE8k ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE8k(BenchContextLE8k ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE16(BenchContextLE16 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE16(BenchContextLE16 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE32(BenchContextLE32 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE32(BenchContextLE32 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE64(BenchContextLE64 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE64(BenchContextLE64 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE128(BenchContextLE128 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE128(BenchContextLE128 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE256(BenchContextLE256 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE256(BenchContextLE256 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE512(BenchContextLE512 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE512(BenchContextLE512 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferLE1m(BenchContextLE1m ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferLE1m(BenchContextLE1m ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE8k(BenchContextBE8k ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE8k(BenchContextBE8k ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE16(BenchContextBE16 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE16(BenchContextBE16 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE32(BenchContextBE32 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE32(BenchContextBE32 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE64(BenchContextBE64 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE64(BenchContextBE64 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE128(BenchContextBE128 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE128(BenchContextBE128 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE256(BenchContextBE256 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE256(BenchContextBE256 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE512(BenchContextBE512 ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE512(BenchContextBE512 ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
@Benchmark | |
public void testHeapBufferBE1m(BenchContextBE1m ctx) throws IOException { | |
doBench(ctx, ctx.getBufHeap()); | |
} | |
@Benchmark | |
public void testDirectBufferBE1m(BenchContextBE1m ctx) throws IOException { | |
doBench(ctx, ctx.getBufDirect()); | |
} | |
private static long readInts(InputStream is, int cnt) throws IOException { | |
long total = 0; | |
try (DataInputStream dis = new DataInputStream(is)) { | |
for (int idx = 0; idx < cnt; idx++) { | |
total += dis.readInt(); | |
} | |
} | |
return total; | |
} | |
@Benchmark | |
public void testOldBufferedIO8k(BenchContextBE1m ctx) throws IOException { | |
long total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
new FileInputStream(ctx.getTempFile().toFile()))) { | |
total = readInts(bis, BenchContextBase.reqSize / 4); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedNIO8k(BenchContextBE1m ctx) throws IOException { | |
long total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
Files.newInputStream(ctx.getTempFile()))) { | |
total = readInts(bis, BenchContextBase.reqSize / 4); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedIO16k(BenchContextBE1m ctx) throws IOException { | |
long total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
new FileInputStream(ctx.getTempFile().toFile()), 16 * 1024)) { | |
total = readInts(bis, BenchContextBase.reqSize / 4); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedNIO16k(BenchContextBE1m ctx) throws IOException { | |
long total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
Files.newInputStream(ctx.getTempFile()), 16 * 1024)) { | |
total = readInts(bis, BenchContextBase.reqSize / 4); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedIO32k(BenchContextBE1m ctx) throws IOException { | |
long total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
new FileInputStream(ctx.getTempFile().toFile()), 32 * 1024)) { | |
total = readInts(bis, BenchContextBase.reqSize / 4); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedNIO32k(BenchContextBE1m ctx) throws IOException { | |
long total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
Files.newInputStream(ctx.getTempFile()), 32 * 1024)) { | |
total = readInts(bis, BenchContextBase.reqSize / 4); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedIO64k(BenchContextBE1m ctx) throws IOException { | |
long total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
new FileInputStream(ctx.getTempFile().toFile()), 64 * 1024)) { | |
total = readInts(bis, BenchContextBase.reqSize / 4); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedNIO64k(BenchContextBE1m ctx) throws IOException { | |
long total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
Files.newInputStream(ctx.getTempFile()), 64 * 1024)) { | |
total = readInts(bis, BenchContextBase.reqSize / 4); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedIO128k(BenchContextBE1m ctx) throws IOException { | |
long total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
new FileInputStream(ctx.getTempFile().toFile()), 128 * 1024)) { | |
total = readInts(bis, BenchContextBase.reqSize / 4); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldBufferedNIO128k(BenchContextBE1m ctx) throws IOException { | |
long total; | |
try (BufferedInputStream bis = new BufferedInputStream( | |
Files.newInputStream(ctx.getTempFile()), 128 * 1024)) { | |
total = readInts(bis, BenchContextBase.reqSize / 4); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldPlainIO(BenchContextBE1m ctx) throws IOException { | |
long total; | |
try (InputStream bis = new FileInputStream( | |
ctx.getTempFile().toFile())) { | |
total = readInts(bis, BenchContextBase.reqSize / 4); | |
} | |
ctx.verify(total); | |
} | |
@Benchmark | |
public void testOldPlainNIO(BenchContextBE1m ctx) throws IOException { | |
long total; | |
try (InputStream bis = Files.newInputStream(ctx.getTempFile())) { | |
total = readInts(bis, BenchContextBase.reqSize / 4); | |
} | |
ctx.verify(total); | |
} | |
/** | |
* IDEから実行する場合は、 | |
* まず先にmvn package等を実行してサポートファイル類を生成しておく必要がある. | |
* (少なくともクラスまたはメソッドのシグネチャを変更追加するたびにmvnでビルドする必要がある。) | |
* その後、IDEから、このメイン関数を呼び出すことができるようになる. | |
* @param args | |
* @throws RunnerException | |
*/ | |
public static void main(String[] args) throws RunnerException { | |
Options opt = new OptionsBuilder() | |
// 実行すべきベンチマークが定義された"クラス名.メソッド名"を正規表現で指定 | |
.include("FileBufferAccess.+Benchmark") | |
//.exclude(FileBufferAccessIntBenchmark.class.getSimpleName() + ".testOld") | |
// ウォームアップイテレーション数 "-wi"オプションに相当 | |
.warmupIterations(10) | |
// イテレーション数 "-i"オプションに相当 | |
.measurementIterations(10) | |
// フォーク数 "-f"オプションに相当 | |
.forks(1) | |
// 1回のテストメソッド実行時間 "-r"オプションに相当 | |
.measurementTime(TimeValue.seconds(1)) | |
// 同時実行スレッド数 (1測定毎のスレッド数 (サンプル数が増える)) | |
// .threads(Math.max(1, Runtime.getRuntime().availableProcessors() / 2)) | |
// 測定するモード = スループット | |
//.timeUnit(TimeUnit.MICROSECONDS) | |
//.mode(Mode.SampleTime) | |
.build(); | |
new Runner(opt).run(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment