简体   繁体   English

为什么一遍又一遍地运行相同的函数(具有递增的值),我的处理时间会减少吗?

[英]Why does my processing time drop when running the same function over and over again (with incremented values)?

I was testing a new Method to replace my old one and made did some speed testing. 我正在测试一种新方法来替代旧方法,并进行了一些速度测试。 When I now look at the graph I see, that the time it takes per iteration drops drastically. 现在,当我查看图表时,每次迭代所花费的时间将大大减少。 在此处输入图片说明

Now I'm wondering why that might be. 现在我想知道为什么会这样。 My quess would be, that my graphics card takes over the heavy work, but the first function iterates n times and the second (the blue one) doesn't have a single iteration but "heavy" calculation work with doubles. 我的问题是,我的图形卡承担了繁重的工作,但是第一个函数迭代n次,第二个函数(蓝色的)没有一个迭代,而是“繁重”的计算工作加倍。

In case system details are needed: OS: Mac OS X 10.10.4 Core: 2.8 GHz Intel Core i7 (4x) GPU: AMD Radeon R9 M370X 2048 MB 如果需要系统详细信息:操作系统:Mac OS X 10.10.4核心:2.8 GHz英特尔酷睿i7(4x)GPU:AMD Radeon R9 M370X 2048 MB

If you need the two functions: 如果需要两个功能:

New One: 新的一个:

private static int sumOfI(int i) {
    int factor;
    float factor_ = (i + 1) / 2;

    factor = (int) factor_;

    return (i % 2 == 0) ? i * factor + i / 2 : i * factor;
}

Old One: 旧的:

private static int sumOfIOrdinary(int j) {
    int result = 0;
    for (int i = 1; i <= j; i++) {
        result += i;
    }
    return result;
}

To clarify my question: Why does the processing time drop that drastically? 为了澄清我的问题:为什么处理时间会急剧减少?

Edit: I understand at least a little bit about cost and such. 编辑:我至少了解一点有关成本等。 I probably didn't explain my test method good enough. 我可能对测试方法的解释不够好。 I have a simple for loop which in this test counted from 0 to 1000 and I fed each value to 1 method and recorded the time it took (for the whole loop to execute), then I did the same with the other method. 我有一个简单的for循环,在此测试中,该循环从0到1000计数,并将每个值馈给1方法并记录了花费的时间(整个循环执行),然后对其他方法进行了同样的处理。

So after the loop reached about 500 the same method took significantly less time to execute. 因此,在循环达到约500个之后,相同的方法花费的时间明显减少。

Java did not calculate anything on the graphic card (without help from other frameworks or classes). Java没有在图形卡上计算任何内容(没有其他框架或类的帮助)。 Also what you think is a "heavy" calculation is kinda easy for a cpu this day (even if division is kinda tricky). 另外,对于今天的CPU,您认为“繁重”的计算也很容易(即使除法有些棘手)。 So speed depends on the bytecode generated and the Java optimisations when running a program and mostly on the Big-O Notation. 因此,速度取决于运行程序时生成的字节码和Java优化,并且主要取决于Big-O表示法。

Your method sumOfI is just x statements to execute so this is O(1), regardless how large your i is its always only this x statements. 您的方法sumOfI只是要执行的x条语句,所以它是O(1),无论您的i多么大,它始终仅此x条语句。 But the sumOfIOrdinary uses one loop and its O(n) this will use y statements + i statements depending on the input. 但是sumOfIOrdinary使用一个循环,其O(n)将根据输入使用y语句+ i语句。

So from the theory and in worst caste sumOfI is always faster as sumOfIOrdinary . 因此,从理论上讲,在最坏的情况下, sumOfI总是比sumOfIOrdinary更快。 You can also see this problem in the bytecode view. 您也可以在字节码视图中看到此问题。 sumOfI is only some load and add and multiply calls to the cpu. sumOfI只是一些load和对cpu的addmultiply调用。 But for a loop the bytecode also uses a goto and needs to return to an older address and needs to execute lines again this will cost time. 但是对于循环来说,字节码也使用goto并且需要返回到较旧的地址,并且需要再次执行行,这将花费时间。

On my VM with i=500000 the first method needs <1 millisecond and the second method because of the loop takes 2-4 millisecond. 在我的i = 500000的VM上,第一种方法需要<1毫秒,而第二种方法由于循环需要2-4毫秒。

Links to explain Big-O-Notation: 解释大O符号的链接:

  1. Simple Big O Notation 简单的大O符号
  2. A beginner's guide to Big O notation Big O符号初学者指南

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM