package org.simpleflatmapper.io;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.infra.Blackhole;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
import java.util.Random;
@State(Scope.Benchmark)
public class CharReadingBenchmark {
private File file;
String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST1234567890!@£$%^&*()_+";
public int fileSize = 50_000_000;
public Charset charset;
@Param({"8192", "32768", "131072"})
private int bufferSize;
@Setup
public void setUp() throws IOException {
charset = Charset.forName("UTF-8");
file = File.createTempFile("test", ".txt");
try (Writer fw = new OutputStreamWriter(new FileOutputStream(file), charset)) {
Random random = new Random();
for(int i = 0; i < fileSize; i++) {
fw.append(chars.charAt(random.nextInt(chars.length())));
}
}
}
@Benchmark
public void reader(Blackhole blackhole) throws IOException {
bufferSize = 4096 * 32;
char[] buffer = new char[bufferSize];
try (FileChannel channel = FileChannel.open(file.toPath())) {
try (Reader reader = Channels.newReader(channel, charset.newDecoder(), -1)) {
int l;
while ((l = reader.read(buffer)) != -1) {
blackhole.consume(buffer);
}
}
}
}
@Benchmark
public void memoryMappedFile(Blackhole blackhole) throws IOException {
char[] buffer = new char[bufferSize];
try (FileChannel channel = FileChannel.open(file.toPath())) {
MappedByteBuffer byteBuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
CharsetDecoder charsetDecoder = charset.newDecoder();
while(byteBuffer.hasRemaining()) {
CoderResult coderResult = charsetDecoder.decode(byteBuffer, CharBuffer.wrap(buffer), true);
blackhole.consume(buffer);
}
}
}
@Benchmark
public void memoryMappedFileBytes(Blackhole blackhole) throws IOException {
byte[] buffer = new byte[bufferSize];
try (FileChannel channel = FileChannel.open(file.toPath())) {
MappedByteBuffer byteBuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
while(byteBuffer.hasRemaining()) {
byteBuffer.get(buffer, 0, Math.min(buffer.length, byteBuffer.remaining()));
blackhole.consume(buffer);
}
}
}
@Benchmark
public void fileChannelBytes(Blackhole blackhole) throws IOException {
byte[] buffer = new byte[bufferSize];
ByteBuffer wrap = ByteBuffer.wrap(buffer);
try (FileChannel channel = FileChannel.open(file.toPath())) {
int l;
while((l = channel.read(wrap)) != -1) {
blackhole.consume(buffer);
wrap.clear();
}
}
}
@Benchmark
public void intputStreamBytes(Blackhole blackhole) throws IOException {
byte[] buffer = new byte[bufferSize];
try (FileChannel channel = FileChannel.open(file.toPath())) {
try (InputStream is = Channels.newInputStream(channel)) {
int l;
while ((l = is.read(buffer)) != -1) {
blackhole.consume(buffer);
}
}
}
}
}