Java 由于JIT编译,卡钳基准测试失败

Java 由于JIT编译,卡钳基准测试失败,java,microbenchmark,caliper,Java,Microbenchmark,Caliper,我得到了一个卡尺基准,它看起来像这样: public Course timeCourseCreation( int i ) { return createCourse( i ); } public Course createCourse( int t ) { Course course = new Course(); for ( int i = 0 + t; i < this.students + t; i++ ) { Student student = new

我得到了一个卡尺基准,它看起来像这样:

public Course timeCourseCreation( int i ) {

  return createCourse( i );
}

public Course createCourse( int t ) {

  Course course = new Course();

  for ( int i = 0 + t; i < this.students + t; i++ ) {
    Student student = new Student();
    student.setAge( ( int ) ( 100 * Math.random() ) + t );
    student.setName( UUID.randomUUID().toString() );
    course.getStudents().add( student );
  }

  for ( int i = 0 + t; i < this.courses + t; i++ ) {
    Topic topic = new Topic();
    topic.setDescription( UUID.randomUUID().toString() );
    topic.setDifficulty( ( int ) ( 10 * Math.random() ) + t );
    topic.setName( UUID.randomUUID().toString() );
    topic.setRating( ( int ) ( 10 * Math.random() ) + t );
    course.getTopics().add( topic );
  }

  return course;
}
异常告诉我,由于JIT编译,基准测试失败那么,在这里如何防止JIT编译?


我已经尝试用随机值初始化数据结构(如代码中所示),尝试在测试中返回值(如代码中所示),并尝试使用
course
对象,例如调用
course.getSize()
。但什么都不管用

您的基准测试不是很有用:您主要测试Math.random和UUID的速度。此外,它“只是”分配一个PoJo(看起来是这样),您期望从中得到什么结果,除了它可能受GC约束或不受GC约束之外

JIT不是您的问题,因为您希望代码加速。我不确定问题出在哪里,当您返回创建的对象时,JIT可能不会抑制代码(除非卡钳工作不可靠)


我怀疑是Math random或GC导致了不稳定的结果。您可以尝试使用JMH,但它不会使度量更有用。

众所周知,JIT会以可怕的方式扰乱代码,使所有度量都绝对不可靠。人们挣扎了很多,试图使事情至少有点正确,但最终写的东西像。这是一个很好的工具,有助于衡量绩效并实际获得有意义的结果。它甚至使你能够,并有大量的,看看这肯定会帮助你解决你的问题


但这是错误的方式。这通常是保密的,但既然你自己找到了正确的方法,我就告诉你。您可以通过使用禁用JIT。那里不用谢我。

你不能对依赖UUID生成的东西进行基准测试。从大多数操作系统获取随机信息取决于操作系统状态、随机池的状态等。 我发现这会引发不可靠的行为


首先,把它扔掉。

谢谢。我将在没有UUID和
Math.random()
的情况下重写代码。我认为保持POJO略有不同是一个好主意,因为我将在以后的基准测试中使用它们。谢谢。@Thomashrig,请不要使用
-Xint
。我是这样读你的帖子的:我需要测量风速。为此,我决定带一支狙击步枪,看看子弹落在目标中心有多远。除了我拿了一把17世纪的步枪,当我试图使用它时,它射入了我的脚。这是因为我的手指扣动了扳机。我怎么才能把手指割掉,这样就不会再发生这种事了?当然我会试试的!听着,我对我的代码的实际速度不感兴趣。对我来说,10毫秒、20毫秒还是100毫秒都不重要。我只想比较两种不同的算法,知道哪一种比另一种更快。也许
-Xint
选项不是为了割断我的手指,而是为了用步枪上的锁不向我开枪。@Thomashrig,我要说的是,在解释模式和完全JIT编译模式下,两种不同算法的相对性能可能会有很大的差异。我手头没有演示,但希望我能得到一个。我知道这一个不是很有用,但它只是一个例子。我的实际基准测试在一个数据结构上测量不同的算法,这个数据结构与上面的
course>student&topic
示例类似。然而,我的基准测试一直失败,我发现这是由于创建了初始数据结构,所以我将其分解为这个示例。但是你是对的,Math.random和UUID是这里最昂贵的部件。
Failed to execute java -cp C:\Users\tuhrig\workspace\XmlVsJson\target\classes;C:\Users\tuhrig\.m2\repository\javax\xml\bind\jaxb-api\2.2.11\jaxb-api-2.2.11.jar;C:\Users\tuhrig\.m2\repository\com\google\code\gson\gson\2.2.4\gson-2.2.4.jar;C:\Users\tuhrig\.m2\repository\com\google\caliper\caliper\0.5-rc1\caliper-0.5-rc1.jar;C:\Users\tuhrig\.m2\repository\com\google\code\findbugs\jsr305\1.3.9\jsr305-1.3.9.jar;C:\Users\tuhrig\.m2\repository\com\google\guava\guava\11.0.1\guava-11.0.1.jar;C:\Users\tuhrig\.m2\repository\com\google\code\java-allocation-instrumenter\java-allocation-instrumenter\2.0\java-allocation-instrumenter-2.0.jar;C:\Users\tuhrig\.m2\repository\asm\asm\3.3.1\asm-3.3.1.jar;C:\Users\tuhrig\.m2\repository\asm\asm-analysis\3.3.1\asm-analysis-3.3.1.jar;C:\Users\tuhrig\.m2\repository\asm\asm-commons\3.3.1\asm-commons-3.3.1.jar;C:\Users\tuhrig\.m2\repository\asm\asm-tree\3.3.1\asm-tree-3.3.1.jar;C:\Users\tuhrig\.m2\repository\asm\asm-util\3.3.1\asm-util-3.3.1.jar;C:\Users\tuhrig\.m2\repository\asm\asm-xml\3.3.1\asm-xml-3.3.1.jar com.google.caliper.InProcessRunner --warmupMillis 3000 --runMillis 1000 --measurementType TIME --marker //ZxJ/ -Dbenchmark=CourseCreation de.tuhrig.Benchmark
starting Scenario{vm=java, trial=0, benchmark=CourseCreation}
[caliper] [starting warmup]
[caliper] [starting measured section]
[caliper] [done measured section]
[caliper] [starting measured section]
...
Error: Doing 2x as much work didn't take 2x as much time! Is the JIT optimizing away the body of your benchmark?
...
An exception was thrown from the benchmark code.
com.google.caliper.ConfigurationException: Failed to execute java -cp C:\Users\tuhrig\workspace\XmlVsJson\target\classes;C:\Users\tuhrig\.m2\repository\javax\xml\bind\jaxb-api\2.2.11\jaxb-api-2.2.11.jar;C:\Users\tuhrig\.m2\repository\com\google\code\gson\gson\2.2.4\gson-2.2.4.jar;C:\Users\tuhrig\.m2\repository\com\google\caliper\caliper\0.5-rc1\caliper-0.5-rc1.jar;C:\Users\tuhrig\.m2\repository\com\google\code\findbugs\jsr305\1.3.9\jsr305-1.3.9.jar;C:\Users\tuhrig\.m2\repository\com\google\guava\guava\11.0.1\guava-11.0.1.jar;C:\Users\tuhrig\.m2\repository\com\google\code\java-allocation-instrumenter\java-allocation-instrumenter\2.0\java-allocation-instrumenter-2.0.jar;C:\Users\tuhrig\.m2\repository\asm\asm\3.3.1\asm-3.3.1.jar;C:\Users\tuhrig\.m2\repository\asm\asm-analysis\3.3.1\asm-analysis-3.3.1.jar;C:\Users\tuhrig\.m2\repository\asm\asm-commons\3.3.1\asm-commons-3.3.1.jar;C:\Users\tuhrig\.m2\repository\asm\asm-tree\3.3.1\asm-tree-3.3.1.jar;C:\Users\tuhrig\.m2\repository\asm\asm-util\3.3.1\asm-util-3.3.1.jar;C:\Users\tuhrig\.m2\repository\asm\asm-xml\3.3.1\asm-xml-3.3.1.jar com.google.caliper.InProcessRunner --warmupMillis 3000 --runMillis 1000 --measurementType TIME --marker //ZxJ/ -Dbenchmark=CourseCreation de.tuhrig.Benchmark
    at com.google.caliper.Runner.measure(Runner.java:309)
    at com.google.caliper.Runner.runScenario(Runner.java:229)
    at com.google.caliper.Runner.runOutOfProcess(Runner.java:378)
    at com.google.caliper.Runner.run(Runner.java:97)
    at com.google.caliper.Runner.main(Runner.java:423)
    at de.tuhrig.CaliperRunner.main(CaliperRunner.java:22)