我正在使用JJH,一个OpenJDK微基准测试工具.构建过程创建microbenchmarks.jar我调用java -jar并传递jar名称和JMH参数.
我想我们应该选择运行基准-server,为什么?
换句话说,我应该运行我的基准:
java -server -jar microbenchmarks.jar ...(jmh args)
Run Code Online (Sandbox Code Playgroud) 有一个错误,JMH没有把我的班级提升到基准.
package com.stecurran.jmh.entry;
import org.openjdk.jmh.Main;
public class JmhRunner {
private static final String TEST = "com.stecurra.benchmark.strategy.EventRunner";
public static void main(String[] args) {
Main.main(getArguments(TEST, 5, 5000, 1));
}
private static String[] getArguments(String className, int nRuns, int runForMilliseconds, int nThreads) {
return new String[] { className, "-i", "" + nRuns, "-r", runForMilliseconds + "ms", "-t", "" + nThreads, "-w", "5000ms", "-wi", "3", "-v" };
}
}
Run Code Online (Sandbox Code Playgroud)
EventRunner包含的位置:
package com.stecurra.benchmark.strategy;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.GenerateMicroBenchmark;
import org.openjdk.jmh.annotations.Mode;
@BenchmarkMode(Mode.AverageTime)
public class EventRunner {
@GenerateMicroBenchmark
public …Run Code Online (Sandbox Code Playgroud) 我很难理解这个基准测试的进展情况.我想测量我的样本类的StringBand工作方式StringBuilder.这个想法StringBand是连接字符串,而toString()不是连接字符串append().
这是StringBand源 - 剥离基准:
public class StringBandSimple {
private String[] array;
private int index;
private int length;
public StringBandSimple(int initialCapacity) {
array = new String[initialCapacity];
}
public StringBandSimple append(String s) {
if (s == null) {
s = StringPool.NULL;
}
if (index >= array.length) {
//expandCapacity();
}
array[index++] = s;
length += s.length();
return this;
}
public String toString() {
if (index == 0) {
return StringPool.EMPTY; …Run Code Online (Sandbox Code Playgroud) 问题1:为什么JMH比简单更好System.getNanotime()?
问题2:从结果(看看benchmarking results部分)我可以得出什么结果validateLongKeyBinary比64%更快validateLongKeyAscii?
示例(代码):
import net.spy.memcached.util.StringUtils;
import org.openjdk.jmh.annotations.GenerateMicroBenchmark;
public class KeyBench {
private static final String LONG_KEY = "thisIsAFunkyKeyWith_underscores_AndAlso334" +
"3252545345NumberslthisIsAFunkyKeyWith_underscores_AndAlso3343252545345Numbe" +
"rslthisIsAFunkyKeyWith_underscores_AndAlso3343252545345NumberslthisIsAFunkyK" +
"eyWith_underscores_AndAlso3343252545345Numbersl";
@GenerateMicroBenchmark
public void validateLongKeyBinary() {
StringUtils.validateKey(LONG_KEY, true);
}
@GenerateMicroBenchmark
public void validateLongKeyAscii() {
StringUtils.validateKey(LONG_KEY, false);
}
}
Run Code Online (Sandbox Code Playgroud)
基准测试结果
# Running: benchmarks.KeyBench.validateLongKeyAscii
Result : 393,667 ±(95%) 13,985 ±(99%) 20,094 ops/ms
Statistics: (min, avg, max) = (357,445, 393,667, 413,004), stdev = 19,552
Confidence intervals: 95% …Run Code Online (Sandbox Code Playgroud) 我有一段代码,在我运行的每个测试中,函数调用都会产生大量的开销.代码是一个紧密的循环,在一个数组的每个元素上执行一个非常简单的函数(包含4-8百万ints).
运行主要由以下内容组成的代码
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);
}
}
Run Code Online (Sandbox Code Playgroud)
执行类似的事情
(final int[] d, final int s, final int x, final int y) -> {
final int p = s * y + x;
final int a = d[p] * 2
+ d[p - 1]
+ d[p …Run Code Online (Sandbox Code Playgroud) 我想对程序(使用JMH)进行基准测试,该程序从文件中读取数据然后测量性能.文件名称存储为列表.问题是@Param只采用常量表达式,所以在某种程度上它意味着我需要对所有文件名进行静态编码@Param,这看起来不太好.
还有另一种方法,为没有静态编码的不同文件运行基准测试吗?
我是JMH和基准测试的新手.我已经编写了一个public byte [] getBytes(String charsetName)方法的小测试.然而,maven无法建立.这是我的代码:
package org.openjdk.jmh.samples;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
public class Test
{ @GenerateMicroBenchmark
public byte [] testgetbyte (String Str)
{
byte[] bytes = Str.getBytes("ISO-8859-1");
return bytes;
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(Test.class.getSimpleName())
.warmupIterations(5)
.measurementIterations(5)
.forks(1)
.build();
new Runner(opt).run();
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行:mvn clean install.我收到Build failure错误消息.
我最近开始与JMH合作,想知道是否有可能对其进行调试。
我做的第一件事是尝试像调试其他程序一样对其进行调试,但是它抛出“未初始化传输”,因此我无法以老式的方式对其进行调试。
我要做的下一件事是尝试在Internet上搜索,发现有人说您需要将forks设置为0,然后对其进行了尝试。
不幸的是,我无法真正理解分支为什么会影响调试,或者分支如何影响我在JMH中看到事情的方式。到目前为止,我所知道的是,当将.forks(number)放在OptionBuilder上时,它会说明基准测试将运行多少个进程。但是,如果我将.forks(3)放在3个进程异步上运行每个@Benchmark方法?
关于.forks(number)、. threads(number)的解释将如何改变基准测试的运行方式以及它们如何影响调试。
我正在学习如何使用JMH对事物进行微观标记.我开始看似简单的东西:StringBuildervs的字符串连接String +=.
根据我的理解,我应该创建一个State包含一个实例的对象,StringBuilder因为我不想对它的构造函数进行基准测试(我也不想每次迭代都是空的).同样适用于String +=测试 - 我希望我的String对象State与新字符串连接.
这是我的代码:
@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class Test {
@State(Scope.Thread)
public static class BenchmarkState {
public StringBuilder builder;
public String regularString;
@Setup(Level.Iteration)
public void setup() {
builder = new StringBuilder();
regularString = "";
}
}
@Benchmark
public String stringTest(BenchmarkState state) {
state.regularString += "hello";
return state.regularString;
}
@Benchmark
public String stringBuilderTest(BenchmarkState state) {
state.builder.append("hello");
return state.builder.toString();
}
public static void main(String[] …Run Code Online (Sandbox Code Playgroud) 我写了两个基准来证明JIT可能是编写精细基准测试的问题(请跳过我在这里不使用@State):
@Fork(value = 1)
@Warmup(iterations = 2, time = 10)
@Measurement(iterations = 3, time = 2)
@BenchmarkMode(Mode.AverageTime)
public class DeadCodeTraps {
@Benchmark
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public static void summaryStatistics_standardDeviationForFourNumbers() {
final SummaryStatistics summaryStatistics = new SummaryStatistics();
summaryStatistics.addValue(10.0);
summaryStatistics.addValue(20.0);
summaryStatistics.addValue(30.0);
summaryStatistics.addValue(40.0);
summaryStatistics.getStandardDeviation();
}
@Benchmark
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public static void summaryStatistics_standardDeviationForTenNumbers() {
final SummaryStatistics summaryStatistics = new SummaryStatistics();
summaryStatistics.addValue(10.0);
summaryStatistics.addValue(20.0);
summaryStatistics.addValue(30.0);
summaryStatistics.addValue(40.0);
summaryStatistics.addValue(50.0);
summaryStatistics.addValue(60.0);
summaryStatistics.addValue(70.0);
summaryStatistics.addValue(80.0);
summaryStatistics.addValue(90.0);
summaryStatistics.addValue(100.0);
summaryStatistics.getStandardDeviation();
}
}
Run Code Online (Sandbox Code Playgroud)
我认为JIT将消除死代码,因此两个方法将同时执行.但最后,我有:
summaryStatistics_standardDeviationForFourNumbers 0.158±0.046 DeadCodeTraps.summaryStatistics_standardDeviationForTenNumbers 0.359±0.294
为什么JIT不优化它?结果summaryStatistics.getStandardDeviation();不会在方法之外的任何地方使用,也不会被它返回.
(我使用的是OpenJDK build 10.0.2 + 13-Ubuntu-1ubuntu0.18.04.4)