- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在对 Java 列表迭代代码运行一些微基准测试。我使用了 -XX:+PrintCompilation 和 -verbose:gc 标志来确保在计时运行时后台没有发生任何事情。但是,我在输出中看到了一些我无法理解的内容。
这是代码,我正在运行基准测试:
import java.util.ArrayList;
import java.util.List;
public class PerformantIteration {
private static int theSum = 0;
public static void main(String[] args) {
System.out.println("Starting microbenchmark on iterating over collections with a call to size() in each iteration");
List<Integer> nums = new ArrayList<Integer>();
for(int i=0; i<50000; i++) {
nums.add(i);
}
System.out.println("Warming up ...");
//warmup... make sure all JIT comliling is done before the actual benchmarking starts
for(int i=0; i<10; i++) {
iterateWithConstantSize(nums);
iterateWithDynamicSize(nums);
}
//actual
System.out.println("Starting the actual test");
long constantSizeBenchmark = iterateWithConstantSize(nums);
long dynamicSizeBenchmark = iterateWithDynamicSize(nums);
System.out.println("Test completed... printing results");
System.out.println("constantSizeBenchmark : " + constantSizeBenchmark);
System.out.println("dynamicSizeBenchmark : " + dynamicSizeBenchmark);
System.out.println("dynamicSizeBenchmark/constantSizeBenchmark : " + ((double)dynamicSizeBenchmark/(double)constantSizeBenchmark));
}
private static long iterateWithDynamicSize(List<Integer> nums) {
int sum=0;
long start = System.nanoTime();
for(int i=0; i<nums.size(); i++) {
// appear to do something useful
sum += nums.get(i);
}
long end = System.nanoTime();
setSum(sum);
return end-start;
}
private static long iterateWithConstantSize(List<Integer> nums) {
int count = nums.size();
int sum=0;
long start = System.nanoTime();
for(int i=0; i<count; i++) {
// appear to do something useful
sum += nums.get(i);
}
long end = System.nanoTime();
setSum(sum);
return end-start;
}
// invocations to this method simply exist to fool the VM into thinking that we are doing something useful in the loop
private static void setSum(int sum) {
theSum = sum;
}
}
这是输出。
152 1 java.lang.String::charAt (33 bytes)
160 2 java.lang.String::indexOf (151 bytes)
165 3Starting microbenchmark on iterating over collections with a call to size() in each iteration java.lang.String::hashCode (60 bytes)
171 4 sun.nio.cs.UTF_8$Encoder::encodeArrayLoop (490 bytes)
183 5
java.lang.String::lastIndexOf (156 bytes)
197 6 java.io.UnixFileSystem::normalize (75 bytes)
200 7 java.lang.Object::<init> (1 bytes)
205 8 java.lang.Number::<init> (5 bytes)
206 9 java.lang.Integer::<init> (10 bytes)
211 10 java.util.ArrayList::add (29 bytes)
211 11 java.util.ArrayList::ensureCapacity (58 bytes)
217 12 java.lang.Integer::valueOf (35 bytes)
221 1% performance.api.PerformantIteration::main @ 21 (173 bytes)
Warming up ...
252 13 java.util.ArrayList::get (11 bytes)
252 14 java.util.ArrayList::rangeCheck (22 bytes)
253 15 java.util.ArrayList::elementData (7 bytes)
260 2% performance.api.PerformantIteration::iterateWithConstantSize @ 19 (59 bytes)
268 3% performance.api.PerformantIteration::iterateWithDynamicSize @ 12 (57 bytes)
272 16 performance.api.PerformantIteration::iterateWithConstantSize (59 bytes)
278 17 performance.api.PerformantIteration::iterateWithDynamicSize (57 bytes)
Starting the actual test
Test completed... printing results
constantSizeBenchmark : 301688
dynamicSizeBenchmark : 782602
dynamicSizeBenchmark/constantSizeBenchmark : 2.5940773249184588
我不明白输出中的这四行。
260 2% performance.api.PerformantIteration::iterateWithConstantSize @ 19 (59 bytes)
268 3% performance.api.PerformantIteration::iterateWithDynamicSize @ 12 (57 bytes)
272 16 performance.api.PerformantIteration::iterateWithConstantSize (59 bytes)
278 17 performance.api.PerformantIteration::iterateWithDynamicSize (57 bytes)
最佳答案
我将尝试在 link 的帮助下回答我自己的问题发表者Thomas Jungblut .
260 2% performance.api.PerformantIteration::iterateWithConstantSize @ 19 (59 bytes)
268 3% performance.api.PerformantIteration::iterateWithDynamicSize @ 12 (57 bytes)
272 16 performance.api.PerformantIteration::iterateWithConstantSize (59 bytes)
278 17 performance.api.PerformantIteration::iterateWithDynamicSize (57 bytes)
第一列
第一列“260”是时间戳。
第二栏
第二列是compile_id和method_attributes。当触发 HotSpot 编译时,每个编译单元都会获得一个编译 ID。第二列中的数字是编译 id。 JIT 编译和 OSR 编译有两种不同的编译 id 序列。所以 1% 和 1 是不同的编译单位。前两行中的 % 表示这是一个 OSR 编译。触发了 OSR 编译,因为代码在一个大循环上循环,并且 VM 确定此代码很热。因此触发了 OSR 编译,这将使 VM 能够执行堆栈替换并在准备好后转移到优化的代码。
第三栏
第三列performance.api.PerformantIteration::iterateWithConstantSize
是方法名。
第四栏
当 OSR 编译发生和不发生时,第四列再次不同。我们先来看看常见的部分。第四列的末尾(59 个字节),指的是编译单元的字节码大小(不是编译代码的大小)。 OSR 编译中的@19 部分指的是osr_bci。我将引用上面提到的链接 -
A "place" in a Java method is defined by its bytecode index (BCI), and the place that triggered an OSR compilation is called the "osr_bci". An OSR-compiled nmethod can only be entered from its osr_bci; there can be multiple OSR-compiled versions of the same method at the same time, as long as their osr_bci differ.
最后,为什么方法编译了两次?
第一个是 OSR 编译,大概是在循环运行时由于预热代码(在示例中)而发生的,第二个编译是 JIT 编译,大概是为了进一步优化编译后的代码?
关于java - 理解-XX :+PrintCompilation的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13086690/
最近在使用 -XX:+PrintCompilation (JDK 8r111) 检查方法编译时,我注意到一个新列没有出现在 documentation 中。我可以find关于主题:
当 JVM 记录我的程序类的编译/反编译时,它是在开始编译/反编译之前记录还是在完成编译/反编译之后记录? 我使用 -XX:+PrintCompilation 请求 JVM 记录。 谢谢, 罗曼 最佳
正如 this answer 中所建议的,我在运行性能测试时使用以下标志。 -XX:+PrintCompilation -verbose:gc 这对于调试计时阶段发生的 JVM Activit
一些热点 JVM 标志,例如 -XX:+PrintCompilation , 使输出出现在 stdout 或 stderr 上。 GC 相关的输出,例如由 -verbose:gc 启用的输出,可以使用
在运行 Java 1.6 (1.6.0_03-b05) 应用程序时,我添加了 -XX:+PrintCompilation 标志。在某些方法的输出中,尤其是我知道的一些方法被调用了很多,我看到文本 ma
我是一名优秀的程序员,十分优秀!