在研究分代垃圾收集器对应用程序性能的微妙后果时,我已经在一个非常基本的操作 - 一个简单的写入堆位置 - 的性能方面遇到了相当惊人的差异 - 关于所写的值是原始值还是引用.
@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() {
final int primitiveValue = val++;
for (int i = 0; i < TARGET_SIZE; i++)
primitiveArray[i] = primitiveValue;
}
@GenerateMicroBenchmark
public void fillReferenceArray() …Run Code Online (Sandbox Code Playgroud) 我目前正在寻找性能。为了衡量吞吐量,并确保我们不会倒退,我使用了很棒的 JMH。
当我遇到的东西是,虽然慢,我要开始剖析,看看是怎么回事,根据这个链接江铃控股的作者写道:
虽然 JMH 分析器可以帮助分析,但我认为它们不能替代正确的分析。例如,“堆栈”分析器很适合浏览配置文件,但不适用于严肃的工作。
更长时间地运行工作负载,并将您选择的分析器附加到正在运行的 VM。
我暗中希望我可以从命令行调整 JMH 测试,然后将诸如visualvm 之类的东西附加到它上面……但到目前为止我已经能够让它工作了。我想这是个坏主意?如果我可以共享我用来分析的代码以及我用来强制执行的代码,那将是理想的。
基准测试是在 intel core i5, Ubuntu
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
Run Code Online (Sandbox Code Playgroud)
我正在比较Collectors.counting和的表现Collectors.summingLong(x -> 1L).这是基准:
public List<Integer> ints = new ArrayList<>();
Collector<Integer, ?, Long> counting = Collectors.counting();
Collector<Integer, ?, Long> summingLong = Collectors.summingLong(x -> 1L);
@Setup
public void setup() throws Exception{
ints.add(new Random().nextInt(1000));
ints.add(new Random().nextInt(1000));
ints.add(new Random().nextInt(1000));
ints.add(new Random().nextInt(1000));
ints.add(new Random().nextInt(1000));
ints.add(new Random().nextInt(1000));
ints.add(new Random().nextInt(1000));
ints.add(new Random().nextInt(1000));
ints.add(new Random().nextInt(1000));
ints.add(new Random().nextInt(1000));
}
@Benchmark
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime) …Run Code Online (Sandbox Code Playgroud) 我之前有一个有关解释JMH输出的问题,大多数人都回答了该问题,但是我用另一个相关问题更新了该问题,但最好将其作为一个单独的问题。
这是原始问题:验证简单的for / lambda比较的JMH测量。
我的问题与“工作”特定级别的流性能有关。以下是上一个问题的摘录结果,说明了我想知道的事情:
Benchmark Mode Cnt Score Error Units
MyBenchmark.shortLengthConstantSizeFor thrpt 200 132278188.475 ± 1132184.820 ops/s
MyBenchmark.shortLengthConstantSizeLambda thrpt 200 18750818.019 ± 171239.562 ops/s
MyBenchmark.mediumLengthConstantSizeFor thrpt 200 55447999.297 ± 277442.812 ops/s
MyBenchmark.mediumLengthConstantSizeLambda thrpt 200 15925281.039 ± 65707.093 ops/s
MyBenchmark.longerLengthConstantSizeFor thrpt 200 3551842.518 ± 42612.744 ops/s
MyBenchmark.longerLengthConstantSizeLambda thrpt 200 2791292.093 ± 12207.302 ops/s
MyBenchmark.longLengthConstantSizeFor thrpt 200 2984.554 ± 57.557 ops/s
MyBenchmark.longLengthConstantSizeLambda thrpt 200 331.741 ± 2.196 ops/s
Run Code Online (Sandbox Code Playgroud)
我期望随着测试从较短的列表转移到较长的列表,流测试的性能应接近“ for”测试的性能。
我看到在“简短”列表中,流性能是“ for”性能的14%。对于中型列表,该比例为29%。对于较长的列表,该比例为78%。到目前为止,趋势是我所期望的。但是,对于长名单来说,它是11%。由于某种原因,与“ for”相比,列表大小为300k(而不是300)导致流的性能下降。
我想知道是否有人可以证实这样的结果,以及他们是否对为什么会发生有任何想法。
我正在使用Java 8的Win7笔记本电脑上运行它。
我的最终目标是使用标准Java集合作为基线,为几个Java原始集合库创建一套全面的基准.在过去,我使用了编写这些微基准的循环方法.我把我在基准测试中的函数放在循环中并迭代100万次以上,这样jit就有机会进行预热.我获取循环的总时间,然后除以迭代次数,以估计单次调用我正在进行基准测试的函数所花费的时间.在最近阅读了关于JMH项目,特别是这个例子之后:JMHSample_11_Loops我看到了这种方法的问题.
我的机器:
Windows 7 64-bit
Core i7-2760QM @ 2.40 GHz
8.00 GB Ram
jdk1.7.0_45 64-bit
Run Code Online (Sandbox Code Playgroud)
这是上面描述的循环方法代码的简单示例:
public static void main(String[] args) {
HashMap<Long, Long> hmap = new HashMap<Long, Long>();
long val = 0;
//populating the hashmap
for (long idx = 0; idx < 10000000; idx++) {
hmap.put(idx, idx);
}
Stopwatch s = Stopwatch.createStarted();
long x = 0;
for (long idx = 0; idx < 10000000; idx++) {
x = hmap.get(idx);
}
s.stop();
System.out.println(s); //5.522 s
System.out.println(x); …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个这样的方法:
static boolean fitsInDouble(long x) {
// return true if x can be represented
// as a numerically-equivalent double
}
Run Code Online (Sandbox Code Playgroud)
我正在努力寻找最有效的实施方案.我选择了一个,然后一个同事运行基准测试并获得了不同的相对结果.对我而言,最快的实施并不是最快的.
这些基准测试有什么问题吗?
package rnd;
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.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;
@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(1)
@Measurement(iterations = 5)
@Warmup(iterations = 5)
public class Benchmarks {
public static void main(String[] args) throws Exception {
Options options = new …Run Code Online (Sandbox Code Playgroud) 这段代码运行正常.重新启动计算机时,它给出了错误:
ERROR: org.openjdk.jmh.runner.RunnerException:
ERROR: Exception while trying to acquire the JMH lock (C:\WINDOWS\/jmh.lock):
Access is denied, exiting. Use -Djmh.ignoreLock=true to forcefully continue.
at org.openjdk.jmh.runner.Runner.run(Runner.java:213)
at org.openjdk.jmh.Main.main(Main.java:71)
Run Code Online (Sandbox Code Playgroud)
Google-int的错误没有帮助.有人能告诉我如何解决它吗?
@State(Scope.Thread)
public class test {
public ConcurrentHashMap<String,Integer> i = new ConcurrentHashMap<String, Integer>(10000);
public ArrayList<String> k = new ArrayList<String>(10000);
public int p=0;
public void setup(){
for(int m=0;m<1000;m++){
int j=ThreadLocalRandom.current().nextInt(0,10000);
String jk=Integer.toString(j);
k.add(jk);
i.put(jk,j);
}
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Warmup(iterations = 3)
@Measurement(iterations = 5)
public void putKey(){
int n=ThreadLocalRandom.current().nextInt(0,10000);
String nk=Integer.toString(n);
k.add(nk);
i.put(nk,n);
} …Run Code Online (Sandbox Code Playgroud) 注意:这与性能问题无关.我只观察到无法解释/理解的性能差异.
在对一些针对Java 9的新开发的代码进行基准测试时,我发现了一些奇怪的东西.HashMap带有5个密钥的(非常)简单基准测试表明,Java 9比Java 8慢得多.这可以解释一下,还是我的(基准)代码完全错误?
码:
@Fork(
jvmArgsAppend = {"-Xmx512M", "-disablesystemassertions"}
)
public class JsonBenchmark {
@State(Scope.Thread)
public static class Data {
final static Locale RUSSIAN = new Locale("ru");
final static Locale DUTCH = new Locale("nl");
final Map<Locale, String> hashmap = new HashMap<>();
public Data() {
hashmap.put(Locale.ENGLISH, "Flat flashing adjustable for flat angled roof with swivel");
hashmap.put(Locale.FRENCH, "Solin pour toit plat inclinée");
hashmap.put(Locale.GERMAN, "Flachdachkragen Flach Schrägdach");
hashmap.put(DUTCH, "Plakplaat vlak/hellend dak inclusief glijschaal");
hashmap.put(RUSSIAN, "?????? ????? ??????? …Run Code Online (Sandbox Code Playgroud) 我想使用 JMH 对我的应用程序进行基准测试。我正在使用带有 gradle 的 JMH 作为构建工具。github 存储库在这里。
但是每当我运行该应用程序时com.demo.aerospike.JMHAerospikeSpringData,都会出现以下错误。
$ gradle run
> Configure project :
Task :jmh Last added: null
> Task :run
JMHAerospikeSpringData is running ...
Exception in thread "main" java.lang.RuntimeException: ERROR: Unable to find the resource: /META-INF/BenchmarkList
at org.openjdk.jmh.runner.AbstractResourceReader.getReaders(AbstractResourceReader.java:98)
at org.openjdk.jmh.runner.BenchmarkList.find(BenchmarkList.java:122)
at org.openjdk.jmh.runner.Runner.internalRun(Runner.java:256)
at org.openjdk.jmh.runner.Runner.run(Runner.java:206)
at com.demo.aerospike.JMHAerospikeSpringData.main(JMHAerospikeSpringData.java:47)
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':run'.
> Process 'command
'/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
* …Run Code Online (Sandbox Code Playgroud) jmh ×10
java ×7
benchmarking ×2
gradle ×1
java-9 ×1
java-stream ×1
jit ×1
jvm ×1
performance ×1
visualvm ×1
yourkit ×1