我是否应该期望Mockito测试中不在方法中的代码由于Java即时编译而运行得更快?

我是否应该期望Mockito测试中不在方法中的代码由于Java即时编译而运行得更快?,java,mockito,jit,Java,Mockito,Jit,我需要帮助做一个小实验。我有两个测试文件: testFileA.java和testFileB.java testFileA.java看起来像 @Test public void test1() throws Throwable { Instant start = Instant.now(); mvc.perform(MockMvcRequestBuilders .post('someEndpoint/

我需要帮助做一个小实验。我有两个测试文件:

testFileA.java
testFileB.java

testFileA.java
看起来像

    @Test
    public void test1() throws Throwable {
        Instant start = Instant.now();
        mvc.perform(MockMvcRequestBuilders
                        .post('someEndpoint/')
                        .andDo(print())
                        .andExpect(status().isCreated())
        Instant end = Instant.now();
        System.out.println(">>>>>>>>>>>>>>>>>End" + Duration.between(start, end));
    }

    @Test
    public void test2() throws Throwable {
        //same contents as test 1
    }

    @Test
    public void test3() throws Throwable {
        //same contents as test 1
    }
    @Test
    public void test1() throws Throwable {
        Instant start = Instant.now();
        this.abstractedCode();
        Instant end = Instant.now();
        System.out.println(">>>>>>>>>>>>>>>>>End" + Duration.between(start, end));
    }

    @Test
    public void test2() throws Throwable {
           //same contents as test 1
    }

    @Test
    public void test3() throws Throwable {
        //same contents as test 1
    }

    public void abstractedCode(){
      mvc.perform(MockMvcRequestBuilders
                        .post('someEndpoint/')
                        .andDo(print())
                        .andExpect(status().isCreated())
    }
testFileB.java
看起来像

    @Test
    public void test1() throws Throwable {
        Instant start = Instant.now();
        mvc.perform(MockMvcRequestBuilders
                        .post('someEndpoint/')
                        .andDo(print())
                        .andExpect(status().isCreated())
        Instant end = Instant.now();
        System.out.println(">>>>>>>>>>>>>>>>>End" + Duration.between(start, end));
    }

    @Test
    public void test2() throws Throwable {
        //same contents as test 1
    }

    @Test
    public void test3() throws Throwable {
        //same contents as test 1
    }
    @Test
    public void test1() throws Throwable {
        Instant start = Instant.now();
        this.abstractedCode();
        Instant end = Instant.now();
        System.out.println(">>>>>>>>>>>>>>>>>End" + Duration.between(start, end));
    }

    @Test
    public void test2() throws Throwable {
           //same contents as test 1
    }

    @Test
    public void test3() throws Throwable {
        //same contents as test 1
    }

    public void abstractedCode(){
      mvc.perform(MockMvcRequestBuilders
                        .post('someEndpoint/')
                        .andDo(print())
                        .andExpect(status().isCreated())
    }
我对
testFileB.java
的期望是,第一个测试将花费更长的时间,而随后的每个测试不会花费那么长的时间,因为重复的代码被重构为方法调用;Java JIT编译器使我们不必再次重新编译相同的代码。我的期望被证明是正确的

我对
testFileA.java
的期望是,每个测试所花的时间与前一个测试一样长,因为公共代码没有被重构成函数,但结果并非如此。行为是一样的,第一次测试的时间稍长,接下来的两次则更短


我猜JVM中发生了一些事情,使得我调用的
mvc.perform()
方法不必一次又一次地重新编译,JIT编译器正在帮助我的程序,尽管它不在我定义的函数中。这是真的吗?

一个明显的非答案:你把时间花在了错误的地方

“JIT优化”带来的好处只在应用程序运行很长时间、调用同一方法数百万次的设置中起作用

JIT的要点不是优化在JVM生命周期中调用一次的测试方法

意思:投入时间来培训如何编写可测试的生产代码,以及如何清理测试代码。这在这里更为重要


当然:单元测试套件的执行时间仍然很重要。但当这成为一个问题时,您很可能会面临编写糟糕的测试,例如使用默认超时等等。。。如果不是几分钟的话,最终的结果是一个测试需要很多秒。这是你关心的事情。但是对于单元测试环境,您绝对不在乎JIT的魔力。

您似乎对JIT和性能度量有着普遍的误解。首先:JIT只有在经过数千次使用后才会生效。除此之外,测量也很困难。首先,请参见。注意,我没有正确地进行基准测试,我可能会将我在测试中看到的时间缩短归因于侥幸?如果没有任何洞察,很难说您到底在运行什么,以及您的结果是什么。是看看我的答案:我认为这真的不值得(太多)跟进。我问题的全部目的是说服我的同事编写更干净的测试,哈哈。我认为,如果我能向他们展示,将普通代码转化为方法会带来可测量的性能收益,那么这可能会说服他们编写更干净的测试,而不是我们的测试以及我们的代码库中目前存在的3000行测试文件/重复代码恐惧。回到绘图板上,我想,我很感激你的回答。然后使用“正确!”的论点。向他们解释:重要的是您的测试运行“足够快”,而且:它们可以很容易地被阅读、理解和增强。它们可以帮助您更快地移动,并快速修复错误。集中精力。毫秒范围内的性能不是您主要关心的。@威尔:关注可测量的生产率提高,而不是运行测试所需的时间长度。几乎可以肯定的是,你应该忽略“运行测试所花费的时间”,而关注可读性。@JonSkeet是的,嗯。很多人说。。。但每次你很马虎的时候,一个测试需要比它应该需要的多1秒。。。当50个人每月做一次,突然之间,你的单元测试套件在一年后还需要10分钟。整个测试库的周转时间经常被忽略。。。除非结果是痛苦的。但是你需要走很多小步才能到达目的地。@GhostCat:是的,缩短测试时间是很好的,但是在你已经完成了干净的测试之后。我想我的意思是,现在(威尔)几乎肯定应该忽略“运行测试所花费的时间”。