Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/460.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中对象创建的性能度量_Java_Performance_Jmh - Fatal编程技术网

Java中对象创建的性能度量

Java中对象创建的性能度量,java,performance,jmh,Java,Performance,Jmh,我试图比较创建某个类的对象与从byte[]创建String的性能。以下是我为此编写的基准: public class MyBenchmark { @Benchmark @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void tsts(Blackhole b) { b.consume(new TestClass(i(), str()));

我试图比较创建某个类的对象与从
byte[]
创建
String
的性能。以下是我为此编写的基准:

public class MyBenchmark {
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public void tsts(Blackhole b) {
        b.consume(new TestClass(i(), str()));
    }

    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public void str(Blackhole b) {
        b.consume(new String(b()));
    }

    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
    public String str(){
        return "asdasfa";
    }

    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
    public int i(){
        return 23;
    }

    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
    public byte[] b(){
        return new byte[]{49, 66, 43, 65, 78, 123, 96, 54};
    }
}
在哪里

private static class TestClass{
    private int i;
    private String s;

    public TestClass(Integer i, String s) {
        this.i = i;
        this.s = s;
    }
}
在我的机器上,我得到了以下结果:

Benchmark         Mode  Cnt   Score   Error  Units
MyBenchmark.str   avgt   20  47.695 ± 1.869  ns/op
MyBenchmark.tsts  avgt   20   6.999 ± 0.191  ns/op

这样做正确吗?或者我在基准测试中犯了一些错误,遗漏了一些东西?

这是因为JIT知道文本字符串isntance(“asdasfa”)的确切地址。因此,在这种情况下,不需要创建新对象。如果反编译str()方法,您可以清楚地看到它:

该方法由一条指令movabs rax,0x1bc1f1440组成,它将一个地址放入rax寄存器,这就是为什么它更快的原因。其他说明是辅助的


对于另一个方法str(Blackhole b),您将看到更多内容,包括一个已编译的字符串构造函数体,通过方法调用获取默认字符集并解码字节数组。

可能JVM优化了
新TestClass()
(类的坏名称,顺便说一句)每次返回相同的单个实例,因此,每次只调用一次
i
str
(更多的坏名称)。说到坏名称,将
str
重载为具有相同名称的两个完全不同的方法是另一个例子。@LewBloch这就是我问这个问题的原因。也许JVM做了我没想到的事情。就像总是返回同一个实例一样。现在尝试使用
-prof gc
-prof perfasm
等,这将是一个启发。在信任基准之前,您必须分析基准。
0x000000010dd1a2b0: sub    rsp,0x18
0x000000010dd1a2b7: mov    QWORD PTR [rsp+0x10],rbp  ;
0x000000010dd1a2bc: movabs rax,0x1bc1f1440    ;   {oop("asdasfa")}
0x000000010dd1a2c6: add    rsp,0x10
0x000000010dd1a2ca: pop    rbp
0x000000010dd1a2cb: test   DWORD PTR [rip+0xfffffffffe642d2f],eax           # 0x000000010c35d000;
0x000000010dd1a2d1: ret