我正在测试一种新的方法来替换我的旧方法,并做了一些速度测试。
现在,当我看到我看到的图表时,每次迭代所花费的时间大幅下降。
现在我想知道为什么会这样。 我的问题是,我的显卡接管繁重的工作,但是第一个函数迭代n次,第二个函数(蓝色的)没有一次迭代,但是#34;重的"计算工作与双打。
如果需要系统详细信息: 操作系统:Mac OS X 10.10.4 核心:2.8 GHz Intel Core i7(4x) GPU:AMD Radeon R9 M370X 2048 MB
如果您需要这两个功能:
新人:
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;
}
老一:
private static int sumOfIOrdinary(int j) {
int result = 0;
for (int i = 1; i <= j; i++) {
result += i;
}
return result;
}
澄清我的问题: 为什么处理时间急剧下降?
编辑: 我至少了解一下成本等等。我可能没有解释我的测试方法足够好。我有一个简单的for循环,在这个测试中从0到1000计数,我将每个值输入1个方法并记录它所花费的时间(对于整个循环执行),然后我对其他方法做了同样的事情。
因此,在循环达到大约500之后,相同的方法执行的时间要少得多。
答案 0 :(得分:2)
Java没有在图形卡上计算任何东西(没有其他框架或类的帮助)。你认为这个“重”计算对于今天的cpu来说有点容易(即使划分有点棘手)。因此,速度取决于生成的字节码和运行程序时的Java优化,主要取决于Big-O表示法。
你的方法sumOfI
只是要执行的x语句所以这是O(1),无论你的i有多大,它总是只有这个x语句。但sumOfIOrdinary
使用一个循环及其O(n),这将使用y语句+ i语句,具体取决于输入。
因此,从理论和最差的种姓sumOfI
总是更快sumOfIOrdinary
。
您还可以在字节码视图中看到此问题。 sumOfI
仅对cpu进行了一些load
和add
以及multiply
调用。但是对于循环,字节码也使用goto
并且需要返回到旧地址并且需要再次执行行,这将花费时间。
在i = 500000的VM上,第一种方法需要<1毫秒,第二种方法因为循环需要2-4毫秒。
解释Big-O-Notation的链接: