Tag: jmh

java缓存方法的结果

我使用 JMH来指定操作的复杂性。 如果您从未与JMH合作过,请不要担心。 JMH将多次启动estimateOperation方法,然后获得平均时间。 问题:[narrow]这个程序每次都会计算Math.cbrt(Integer.MAX_VALUE)吗? 或者它只计算一次然后返回缓存结果? @GenerateMicroBenchmark public void estimateOperation() { calculate(); } public int calculate() { return Math.cbrt(Integer.MAX_VALUE); } 问题:[broad]: JVM是否会缓存方法的结果?

Arrays.stream()。map()。sum()的不稳定性能

我偶然发现了一个非常不稳定的性能曲线实例,它对原始数组进行了非常简单的map / reduce操作。 这是我的jmh基准代码: @OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) @OperationsPerInvocation(Measure.ARRAY_SIZE) @Warmup(iterations = 300, time = 200, timeUnit=MILLISECONDS) @Measurement(iterations = 1, time = 1000, timeUnit=MILLISECONDS) @State(Scope.Thread) @Threads(1) @Fork(1) public class Measure { static final int ARRAY_SIZE = 1<(int)(Math.random()*(1< multiplier*d; } @Benchmark public double multiply() { return Arrays.stream(ds).map(mapper).sum(); } } 以下是典型输出的片段: # VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/bin/java # VM options: # Warmup: […]

具有恒定长度的System.arraycopy

我正在玩JMH( http://openjdk.java.net/projects/code-tools/jmh/ ),我偶然发现了一个奇怪的结果。 我正在对数组的浅层副本进行基准测试,我可以观察到预期的结果(循环遍历数组是一个坏主意,并且#clone() , System#arraycopy()和Arrays#copyOf()之间没有显着差异Arrays#copyOf() ,性能方面)。 当数组的长度是硬编码时System#arraycopy()减慢四分之一……等等,什么? 怎么会这么慢? 有没有人知道可能是什么原因? 结果(吞吐量): # JMH 1.11 (released 17 days ago) # VM version: JDK 1.8.0_05, VM 25.5-b02 # VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/bin/java # VM options: -Dfile.encoding=UTF-8 -Duser.country=FR -Duser.language=fr -Duser.variant # Warmup: 20 iterations, 1 s each # Measurement: 20 iterations, 1 s each # Timeout: 10 min per […]

了解jvm中的循环性能

我正在玩jmh ,在关于循环的部分,他们说 您可能会注意到重复计数越大,所测量操作的“感知”成本就越低。 到目前为止,我们每增加1/20 ns,远远超出硬件实际可行的范围。 发生这种情况是因为循环被大量展开/流水线化 ,并且要从循环中提升要测量的操作。 士气:不要过度使用循环,依靠JMH来正确测量。 我亲自尝试过 @Benchmark @OperationsPerInvocation(1) public int measurewrong_1() { return reps(1); } @Benchmark @OperationsPerInvocation(1000) public int measurewrong_1000() { return reps(1000); } 得到以下结果: Benchmark Mode Cnt Score Error Units MyBenchmark.measurewrong_1 avgt 15 2.425 ± 0.137 ns/op MyBenchmark.measurewrong_1000 avgt 15 0.036 ± 0.001 ns/op 它确实表明MyBenchmark.measurewrong_1000比MyBenchmark.measurewrong_1 。 但我无法真正理解JVM的优化,以提高性能。 他们的意思是循环展开/流水线 ?

是否有可能使java.lang.invoke.MethodHandle与直接调用一样快?

我正在比较MethodHandle::invoke和直接静态方法MethodHandle::invoke性能。 这是静态方法: public class IntSum { public static int sum(int a, int b){ return a + b; } } 这是我的基准: @State(Scope.Benchmark) public class MyBenchmark { public int first; public int second; public final MethodHandle mhh; @Benchmark @OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) public int directMethodCall() { return IntSum.sum(first, second); } @Benchmark @OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) public int finalMethodHandle() throws Throwable { […]

CPU的div指令和HotSpot的JIT代码之间存在较大的性能差距

从CPU的开始,一般知道整数除法指令是昂贵的。 我看到今天有多糟糕的CPU,它拥有数十亿晶体管的奢侈品。 我发现硬件idiv指令对于常量除数的性能仍然比JIT编译器能够发出的代码差得多,后者不包含idiv指令。 为了在专用的微基准测试中实现这一点,我写了以下内容: @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @OperationsPerInvocation(MeasureDiv.ARRAY_SIZE) @Warmup(iterations = 8, time = 500, timeUnit = TimeUnit.MILLISECONDS) @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) @State(Scope.Thread) @Fork(1) public class MeasureDiv { public static final int ARRAY_SIZE = 128; public static final long DIVIDEND_BASE = 239520948509234807L; static final int DIVISOR = 10; final long[] input = […]

什么可以解释写入堆位置引用的巨大性能损失?

在研究分代垃圾收集器对应用程序性能的微妙后果时,我已经在一个非常基本的操作 – 一个简单的写入堆位置 – 的性能方面遇到了相当惊人的差异,关于所写的值是原始值还是引用。 微基准 @OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) @Warmup(iterations = 1, time = 1) @Measurement(iterations = 3, time = 1) @State(Scope.Thread) @Threads(1) @Fork(2) public class Writing { static final int TARGET_SIZE = 1024; static final int[] primitiveArray = new int[TARGET_SIZE]; static final Object[] referenceArray = new Object[TARGET_SIZE]; int val = 1; @GenerateMicroBenchmark public void fillPrimitiveArray() […]

JMH:在所有Benchmark测试中使用相同的静态对象

我有一个类构造一些复杂的数据(想象一个大的XML或JSON结构 – 那种事情)。 构建它需要时间。 所以我想构建一次,然后在所有测试中使用相同的数据。 目前我基本上在一个定义main的类中定义了一个public static对象实例,然后在测试中显式引用它(代码是一个非常简单的例子): public class Data { // This class constructs some complicated data } public class TestSet { public static final Data PARSE_ME = new Data(…); public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(“.*ParserTest”) // several tests .forks(1) .build(); new Runner(opt).run(); } } @State(Scope.Thread) […]

JMH无法找到资源:/ META-INF / BenchmarkList

我无法在eclipse中运行简单的JMH基准测试。 Maven依赖: org.openjdk.jmh jmh-core 1.12 org.openjdk.jmh jmh-generator-annprocess 1.12 Java代码: public class BTest { @Benchmark public void test() { // todo } public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(BTest.class.getSimpleName()) .build(); new Runner(opt).run(); } } 运行结果: 线程“main”中的exceptionjava.lang.RuntimeException:错误:无法在org.openjdk的org.openjdk.jmh.runner.AbstractResourceReader.getReaders(AbstractResourceReader.java:96)中找到资源:/ META-INF / BenchmarkList。 jmh.runner.BenchmarkList.find(BenchmarkList.java:104)org.openjdk.jmh.runner.Runner.internalRun(Runner.java:256)org.openjdk.jmh.runner.Runner.run(Runner.java: 206)at com.test.BTest.main(BTest.java:24) 也许问题是,我正在从eclipse运行它。 谢谢你的帮助。

最小化Java函数调用开销

我有一段代码 ,在我运行的每个测试中,函数调用都会产生大量的开销。 代码是一个紧密循环,对数组的每个元素执行一个非常简单的函数(包含4-8百万个int )。 运行代码,主要包含 for (int y = 1; y < h; ++y) { for (int x = 1; x < w; ++x) { final int p = y * s + x; n[p] = f.apply(d, s, x, y); } } 执行类似的事情 (final int[] d, final int s, final int x, final int y) […]