Java—执行时间

Java—执行时间,java,time,invoke,execution,Java,Time,Invoke,Execution,我有以下代码: public static void main(String[] args) { long f = System.nanoTime(); int a = 10 + 10; long s =System.nanoTime(); System.out.println(s - f); long g = System.nanoTime(); int b = 10 + 10 + 10 + 10 + 10 + 10 + 10 + 1

我有以下代码:

public static void main(String[] args) {

    long f = System.nanoTime();

    int a = 10 + 10;

    long s =System.nanoTime();

    System.out.println(s - f);

    long g = System.nanoTime();

    int b = 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10;

    long h =System.nanoTime();

    System.out.println(h - g);

}
使用此输出/s: 测试1:

测试2:

533
300
测试3:

431
398
根据我的测试场景,为什么线int b=10+10+10+10+10+10+10+10+10+10+10+10+10+10+10;执行速度比int a=10+10

首先。Java编译器执行常量表达式的优化,因此编译时的代码将转换为:

int b = 120;
结果JVM几乎同时执行分配给a=20和b=120

第二个。你们对大系统进行短期测量,我指的是整个计算机,包括操作系统、交换进程、另一个运行进程。。。。所以你们可以在很短的时间内得到随机系统的快照。这就是为什么不能推断赋值比b快的原因。为了证明这一点,您必须将代码度量放入一个相当大的循环中——同样做大约1000000次。这样大的重复首先可以让你在数学意义上平滑这个词的期望。Java编译器执行常量表达式的优化,因此编译时的代码将转换为:

int b = 120;
结果JVM几乎同时执行分配给a=20和b=120


第二个。你们对大系统进行短期测量,我指的是整个计算机,包括操作系统、交换进程、另一个运行进程。。。。所以你们可以在很短的时间内得到随机系统的快照。这就是为什么不能推断赋值比b快的原因。为了证明这一点,您必须将代码度量放入一个相当大的循环中——同样做大约1000000次。如此大的重复可以让你在数学意义上平滑这个词的期望

这不是衡量绩效的正确方法

首先,不要测量这样一小段代码。 相反,像@NilsH建议的那样,将其称为数百万次, 然后将经过的时间除以呼叫数,得到平均时间

其次,JVM可能会对您的代码执行优化, 所以你需要给它一个热身的时间。 让数百万人在干燥的环境中运行,而根本不测量时间,
然后开始测量。

这不是测量性能的正确方法

首先,不要测量这样一小段代码。 相反,像@NilsH建议的那样,将其称为数百万次, 然后将经过的时间除以呼叫数,得到平均时间

其次,JVM可能会对您的代码执行优化, 所以你需要给它一个热身的时间。 让数百万人在干燥的环境中运行,而根本不测量时间,
然后开始测量。

微基准是出了名的困难,特别是在Java等智能语言中,编译器和热点可以进行大量优化。几乎可以肯定的是,您并没有测试您认为正在测试的内容。阅读更多的细节和例子,这是一篇相当古老的文章,但原则仍然有效

在这种情况下,我可以立即看到至少三个问题:

代码根本不会执行任何加法,因为编译器将为变量分配其编译时常量值。i、 就好像你的代码读INTA=20;int b=120; 在大多数系统上,纳米时间的粒度相当高。再加上操作系统的负载,这意味着测量中的实验误差远大于结果本身的大小。 即使正在添加,您也没有预热VM;通常,由于这个原因,您放置在第二位的任何操作都会显示得更快。 可能还有更多潜在的危险


这个故事的寓意是在现实世界的条件下测试代码,看看它是如何运行的。孤立地测试小块代码并假设总体性能将是这些代码的总和是不准确的。

微基准是出了名的难以获得的,特别是在Java等智能语言中,编译器和Hotspot可以进行大量优化。几乎可以肯定的是,您并没有测试您认为正在测试的内容。阅读更多的细节和例子,这是一篇相当古老的文章,但原则仍然有效

在这种情况下,我可以立即看到至少三个问题:

代码根本不会执行任何加法,因为编译器将为变量分配其编译时常量值。i、 就好像你的代码读INTA=20;int b=120; 在大多数系统上,纳米时间的粒度相当高。再加上操作系统的负载,这意味着测量中的实验误差远大于结果本身的大小。 即使正在添加,您也没有预热VM;通常,由于这个原因,您放置在第二位的任何操作都会显示得更快。 可能还有更多潜在的危险

这个故事的寓意是考验
您的代码在真实环境中运行,以查看其行为。孤立地测试小块代码并假设总体性能将是这些代码的总和是不准确的。

在主方法中一次运行就得出结论是非常不确定的。在一个循环中至少运行几百万次。Micheal请检查下面的URL。java中整数类型的到期池行为会导致后一个类型运行得更快,因为当整数b被执行时,10已经在池中。希望这有帮助。每次运行此代码时,我都会得到不同的结果,从两者的0到600,有时其中一个是0。这些操作太快,您无法一次性对其进行测试。如果您的代码在编译时未进行优化,请使用javap-c检查字节码。此外,它似乎是运行时优化的一个很好的候选变量,因为没有使用变量a和b。所有的代码测试都是System.nanoTime调用。这不是一个好的测试。a和b的值是在编译时计算的常量,因此在编译时实际上没有发生任何事情。在主方法中运行一次就得出结论是非常不确定的。在一个循环中至少运行几百万次。Micheal请检查下面的URL。java中整数类型的到期池行为会导致后一个类型运行得更快,因为当整数b被执行时,10已经在池中。希望这有帮助。每次运行此代码时,我都会得到不同的结果,从两者的0到600,有时其中一个是0。这些操作太快,您无法一次性对其进行测试。如果您的代码在编译时未进行优化,请使用javap-c检查字节码。此外,它似乎是运行时优化的一个很好的候选变量,因为没有使用变量a和b。所有的代码测试都是System.nanoTime调用。这不是一个好的测试。a和b的值是编译时计算的常数,因此,此时实际上什么也没有发生。这可以通过检查生成的字节码bipush 20和bipush 120轻松确认。大系统还包括JVM本身。这可以通过检查生成的字节码bipush 20和bipush 120轻松确认。大系统还包括JVM本身。这一个清除了我的路径。我的意思是,所有的答案都有相同的观点。但这一条详细说明了我做错了什么,这一条为我扫清了道路。我的意思是,所有的答案都有相同的观点。但这一条详细说明了我做错了什么。