我对Java比较陌生,我很好奇Java如何在与C ++相关的普通任务上表现。因此,我将2个C ++字符串格式化方法(sprintf和ostringstream)与使用Java的StringBuilder进行了比较。对于每个可执行文件,我传递的第一个参数是要测量的迭代次数,因此所有代码看起来大致类似于
int numIterations = args[0]; // or argv[1] in C++
// measure begin here, ie:
int begin = System.nanoTime();
// loop to measure
for (int i = 0; i < numIterations; ++i)
{
// formatting code
}
// measure end here, ie
int end = System.nanoTime();
这与我看到其他人如何描述Java代码有关。我注意到,对于少量的迭代(比如说1000),Java的表现非常糟糕。对于大量的迭代,(比如说1,000,000),Java的表现相对较好:
1000次迭代
$ ./spf.out 1000
C++ took: 1412618 ns
$ ./oss.out 1000
C++ took: 1816222 ns
$ java StringBuilderTest 1000
Java took: 25787951 ns
使用1000000次迭代
$ ./spf.out 1000000
C++ took: 1658699148 ns
$ ./oss.out 1000000
C++ took: 2053606449 ns
$java StringBuilderTest 1000000
Java took: 595965442 ns
我怀疑使用开始/结束计时器来分析java代码的方法,因为我不确定JITer是如何工作的。这是一种测量Java代码的虚拟方法吗?使用JIT'er运行代码时,Java是否有更多的“热身”?什么是分析Java代码的规范方法。有没有办法在测量性能之前预热JITer?或者它是否只是被理解为小N JITing将成为测量的性能数字的一部分?
答案 0 :(得分:1)
这是一种测量Java代码的虚拟方法吗?
对于显示的代码是。 Java在消除无法执行任何操作的代码方面比C ++更加智能。在Java显着更快的10个基准测试中,有9个是这种情况。
使用JIT'er运行代码时,Java是否有更多的“热身”?
是的,热身经历了各个阶段。确保你运行测试2-10秒,它应该足够温暖。你可能会忽略前10K - 20K的运行。
分析Java代码的规范方法是什么。有没有办法在测量性能之前预热JITer?
有很多方法。这是最简单的之一。
long begin = 0;
// loop to measure
for (int i = -11000; i < numIterations; ++i)
if (i == 0) begin = System.nanoTime();
或者它是否只是被理解为小N JITing将成为测量性能数据的一部分?
这取决于您想要进行测试的真实程度。如果在生产中代码不会被调用10,000次而且它不会完全预热,那就是你应该测量的。
答案 1 :(得分:0)
1000次迭代来预热VM;可以有点低,我用10万,但在开始测量前热身。 对于基准测试的输出,如果添加“每次调用的时间”,则更好的是readbale,而不仅仅是总时间。
答案 2 :(得分:0)
这个blog article在很大程度上验证了我在热点虚拟机上所看到的内容。
总结一下,是的,HotSpot VM会在一段时间内热身。像我这样的很多新手发布了很多错误的性能测试,因为他们正在测量VM的预热时间。
引用文章:
在预热期间,不要从绩效统计中得出结论!
- 执行测试,测量吞吐量直至稳定。您应该放弃在预热期间获得的统计数据。
- 确保您了解测试场景的预热时间。我们使用10-15分钟的预热时间,这足以满足我们的需求。但亲自测试一下! JVM需要一段时间来检测热点并编译正在运行的代码。