blob: 9c82236c8f2a077c67902b975655635d9b7f3928 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.test.microbench;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.util.PrimitiveIterator;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import org.apache.cassandra.io.util.BufferedDataOutputStreamPlus;
import org.apache.cassandra.io.util.DataOutputPlus;
import org.apache.cassandra.utils.vint.VIntCoding;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(value = 3, jvmArgsAppend = "-Xmx512M")
@Threads(1)
@State(Scope.Benchmark)
public class VIntCodingBench
{
long oneByte = 53;
long twoBytes = 10201;
long threeBytes = 1097151L;
long fourBytes = 168435455L;
long fiveBytes = 33251130335L;
long sixBytes = 3281283447775L;
long sevenBytes = 417672546086779L;
long eightBytes = 52057592037927932L;
long nineBytes = 72057594037927937L;
final static String MONOMORPHIC = "monomorphic";
final static String BIMORPHIC = "bimorphic";
final static String MEGAMORPHIC = "megamorphic";
@Param({ MONOMORPHIC, BIMORPHIC, MEGAMORPHIC})
String allocation;
final Random random = new Random(100);
final PrimitiveIterator.OfLong longs = random.longs().iterator();
final static int BUFFER_SIZE = 8192;
ByteBuffer onheap = ByteBuffer.allocate(BUFFER_SIZE);
ByteBuffer direct = ByteBuffer.allocateDirect(BUFFER_SIZE);
File mmapedFile = new File(VIntCodingBench.class + "_mmap");
ByteBuffer mmaped = allocateMmapedByteBuffer(mmapedFile, BUFFER_SIZE);
@TearDown
public void tearDown()
{
mmapedFile.delete();
}
private static ByteBuffer allocateMmapedByteBuffer(File mmapFile, int bufferSize)
{
try(RandomAccessFile file = new RandomAccessFile(mmapFile, "rw");
FileChannel ch = file.getChannel())
{
return ch.map(FileChannel.MapMode.READ_WRITE, 0, bufferSize);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
private ByteBuffer getByteBuffer(String allocation)
{
ByteBuffer buffer;
if (allocation.equals(MONOMORPHIC))
{
buffer = onheap;
}
else if (allocation.equals(BIMORPHIC))
{
buffer = random.nextBoolean() ? onheap : direct;
}
else
{
switch(random.nextInt(3))
{
case 0:
buffer = onheap;
break;
case 1:
buffer = direct;
break;
default:
buffer = mmaped;
break;
}
}
return buffer;
}
private DataOutputPlus getBufferedDataOutput(Blackhole bh, ByteBuffer buffer)
{
WritableByteChannel wbc = new WritableByteChannel() {
@Override
public boolean isOpen()
{
return true;
}
@Override
public void close() throws IOException
{
}
@Override
public int write(ByteBuffer src) throws IOException
{
bh.consume(src);
int remaining = src.remaining();
src.position(src.limit());
return remaining;
}
};
return new BufferedDataOutputStreamPlus(wbc, buffer);
}
@Benchmark
public void testWrite1ByteBB(final Blackhole bh)
{
ByteBuffer buffer = getByteBuffer(allocation);
VIntCoding.writeUnsignedVInt(oneByte, buffer);
bh.consume(buffer);
buffer.clear();
}
@Benchmark
public void testWrite1ByteDOP(final Blackhole bh) throws IOException
{
ByteBuffer buffer = getByteBuffer(allocation);
DataOutputPlus out = getBufferedDataOutput(bh, buffer);
VIntCoding.writeUnsignedVInt(oneByte, out);
bh.consume(out);
buffer.clear();
}
@Benchmark
public void testWrite2BytesBB(final Blackhole bh)
{
ByteBuffer buffer = getByteBuffer(allocation);
VIntCoding.writeUnsignedVInt(twoBytes, buffer);
bh.consume(buffer);
buffer.clear();
}
@Benchmark
public void testWrite2BytesDOP(final Blackhole bh) throws IOException
{
ByteBuffer buffer = getByteBuffer(allocation);
DataOutputPlus out = getBufferedDataOutput(bh, buffer);
VIntCoding.writeUnsignedVInt(twoBytes, out);
bh.consume(out);
buffer.clear();
}
@Benchmark
public void testWrite3BytesBB(final Blackhole bh)
{
ByteBuffer buffer = getByteBuffer(allocation);
VIntCoding.writeUnsignedVInt(threeBytes, buffer);
bh.consume(buffer);
buffer.clear();
}
@Benchmark
public void testWrite3BytesDOP(final Blackhole bh) throws IOException
{
ByteBuffer buffer = getByteBuffer(allocation);
DataOutputPlus out = getBufferedDataOutput(bh, buffer);
VIntCoding.writeUnsignedVInt(threeBytes, out);
bh.consume(out);
buffer.clear();
}
@Benchmark
public void testWrite4BytesBB(final Blackhole bh)
{
ByteBuffer buffer = getByteBuffer(allocation);
VIntCoding.writeUnsignedVInt(fourBytes, buffer);
bh.consume(buffer);
buffer.clear();
}
@Benchmark
public void testWrite4BytesDOP(final Blackhole bh) throws IOException
{
ByteBuffer buffer = getByteBuffer(allocation);
DataOutputPlus out = getBufferedDataOutput(bh, buffer);
VIntCoding.writeUnsignedVInt(fourBytes, out);
bh.consume(out);
buffer.clear();
}
@Benchmark
public void testWrite5BytesBB(final Blackhole bh)
{
ByteBuffer buffer = getByteBuffer(allocation);
VIntCoding.writeUnsignedVInt(fiveBytes, buffer);
bh.consume(buffer);
buffer.clear();
}
@Benchmark
public void testWrite5BytesDOP(final Blackhole bh) throws IOException
{
ByteBuffer buffer = getByteBuffer(allocation);
DataOutputPlus out = getBufferedDataOutput(bh, buffer);
VIntCoding.writeUnsignedVInt(fiveBytes, out);
bh.consume(out);
buffer.clear();
}
@Benchmark
public void testWrite6BytesBB(final Blackhole bh)
{
ByteBuffer buffer = getByteBuffer(allocation);
VIntCoding.writeUnsignedVInt(sixBytes, buffer);
bh.consume(buffer);
buffer.clear();
}
@Benchmark
public void testWrite6BytesDOP(final Blackhole bh) throws IOException
{
ByteBuffer buffer = getByteBuffer(allocation);
DataOutputPlus out = getBufferedDataOutput(bh, buffer);
VIntCoding.writeUnsignedVInt(sixBytes, out);
bh.consume(out);
buffer.clear();
}
@Benchmark
public void testWrite7BytesBB(final Blackhole bh)
{
ByteBuffer buffer = getByteBuffer(allocation);
VIntCoding.writeUnsignedVInt(sevenBytes, buffer);
bh.consume(buffer);
buffer.clear();
}
@Benchmark
public void testWrite7BytesDOP(final Blackhole bh) throws IOException
{
ByteBuffer buffer = getByteBuffer(allocation);
DataOutputPlus out = getBufferedDataOutput(bh, buffer);
VIntCoding.writeUnsignedVInt(sevenBytes, out);
bh.consume(out);
buffer.clear();
}
@Benchmark
public void testWrite8BytesBB(final Blackhole bh)
{
ByteBuffer buffer = getByteBuffer(allocation);
VIntCoding.writeUnsignedVInt(eightBytes, buffer);
bh.consume(buffer);
buffer.clear();
}
@Benchmark
public void testWrite8BytesDOP(final Blackhole bh) throws IOException
{
ByteBuffer buffer = getByteBuffer(allocation);
DataOutputPlus out = getBufferedDataOutput(bh, buffer);
VIntCoding.writeUnsignedVInt(eightBytes, out);
bh.consume(out);
buffer.clear();
}
@Benchmark
public void testWrite9BytesBB(final Blackhole bh)
{
ByteBuffer buffer = getByteBuffer(allocation);
VIntCoding.writeUnsignedVInt(nineBytes, buffer);
bh.consume(buffer);
buffer.clear();
}
@Benchmark
public void testWrite9BytesDOP(final Blackhole bh) throws IOException
{
ByteBuffer buffer = getByteBuffer(allocation);
DataOutputPlus out = getBufferedDataOutput(bh, buffer);
VIntCoding.writeUnsignedVInt(nineBytes, out);
bh.consume(out);
buffer.clear();
}
@Benchmark
public void testWriteRandomLongBB(final Blackhole bh)
{
ByteBuffer buffer = getByteBuffer(allocation);
VIntCoding.writeUnsignedVInt(longs.nextLong(), buffer);
bh.consume(buffer);
buffer.clear();
}
@Benchmark
public void testWriteRandomLongDOP(final Blackhole bh) throws IOException
{
ByteBuffer buffer = getByteBuffer(allocation);
DataOutputPlus out = getBufferedDataOutput(bh, buffer);
VIntCoding.writeUnsignedVInt(longs.nextLong(), out);
bh.consume(out);
buffer.clear();
}
@Benchmark
public void testComputeUnsignedVIntSize(final Blackhole bh)
{
bh.consume(VIntCoding.computeUnsignedVIntSize(longs.nextLong()));
}
}