|
package org.openjdk.jmh.samples; |
|
|
|
import org.openjdk.jmh.annotations.*; |
|
import org.openjdk.jmh.runner.Runner; |
|
import org.openjdk.jmh.profile.DTraceAsmProfiler; |
|
import org.openjdk.jmh.runner.RunnerException; |
|
import org.openjdk.jmh.runner.options.Options; |
|
import org.openjdk.jmh.runner.options.OptionsBuilder; |
|
|
|
import java.nio.ByteBuffer; |
|
import java.util.concurrent.TimeUnit; |
|
|
|
@BenchmarkMode(Mode.AverageTime) |
|
@OutputTimeUnit(TimeUnit.NANOSECONDS) |
|
@Warmup(iterations = 5, time = 1) |
|
@Measurement(iterations = 5, time = 1) |
|
@Fork(1) |
|
@State(Scope.Benchmark) |
|
public class Propagation { |
|
|
|
private static final Field[] FIELDS = new Field[]{ |
|
new FloatField(), new DoubleField(), new LongField(), new IntField() |
|
}; |
|
|
|
private static final ByteBuffer BUF = ByteBuffer.allocateDirect(64); |
|
|
|
static { |
|
BUF.putLong(1L); |
|
} |
|
|
|
public static void main(String[] args) throws RunnerException { |
|
Options opt = new OptionsBuilder() |
|
.include(".*" + Propagation.class.getSimpleName() + ".*") |
|
// .addProfiler(DTraceAsmProfiler.class) |
|
.build(); |
|
|
|
new Runner(opt).run(); |
|
} |
|
|
|
@Benchmark |
|
public void inplace() { |
|
Field[] array = new Field[]{ |
|
new FloatField(), new DoubleField(), new LongField(), new IntField() |
|
}; |
|
|
|
for (Field field : array) { |
|
field.read(BUF); |
|
} |
|
} |
|
|
|
@Benchmark |
|
public void constant() { |
|
for (Field field : FIELDS) { |
|
field.read(BUF); |
|
} |
|
} |
|
|
|
@Benchmark |
|
public void varargs() { |
|
readVarargs(new FloatField(), new DoubleField(), new LongField(), new IntField()); |
|
} |
|
|
|
@Benchmark |
|
public void hadnrolled() { |
|
Field[] array = new Field[]{ |
|
new FloatField(), new DoubleField(), new LongField(), new IntField() |
|
}; |
|
|
|
for (int i = 0; i < array.length; i += 4) { |
|
array[i].read(BUF); |
|
array[i + 1].read(BUF); |
|
array[i + 2].read(BUF); |
|
array[i + 3].read(BUF); |
|
} |
|
} |
|
|
|
@Benchmark |
|
public void hadnrolledConstant() { |
|
Field[] array = new Field[]{ |
|
new FloatField(), new DoubleField(), new LongField(), new IntField() |
|
}; |
|
|
|
array[0].read(BUF); |
|
array[1].read(BUF); |
|
array[2].read(BUF); |
|
array[3].read(BUF); |
|
} |
|
|
|
@Benchmark |
|
public void manual() { |
|
new FloatField().read(BUF); |
|
new DoubleField().read(BUF); |
|
new LongField().read(BUF); |
|
new IntField().read(BUF); |
|
} |
|
|
|
private void readVarargs(Field... fields) { |
|
for (Field field : fields) { |
|
field.read(BUF); |
|
} |
|
} |
|
|
|
interface Field { |
|
void read(ByteBuffer buffer); |
|
} |
|
|
|
static class FloatField implements Field { |
|
float f; |
|
|
|
@Override |
|
public void read(ByteBuffer buffer) { |
|
f = buffer.getFloat(0); |
|
} |
|
} |
|
|
|
static class DoubleField implements Field { |
|
double d; |
|
|
|
@Override |
|
public void read(ByteBuffer buffer) { |
|
d = buffer.getDouble(0); |
|
} |
|
} |
|
|
|
static class LongField implements Field { |
|
long l; |
|
|
|
@Override |
|
public void read(ByteBuffer buffer) { |
|
l = buffer.getLong(0); |
|
} |
|
} |
|
|
|
static class IntField implements Field { |
|
int i; |
|
|
|
@Override |
|
public void read(ByteBuffer buffer) { |
|
i = buffer.getInt(0); |
|
} |
|
} |
|
|
|
} |