相关疑难解决方法(0)

为什么40亿次迭代的Java循环只需2 ms?

我在配备2.7 GHz Intel Core i7的笔记本电脑上运行以下Java代码.我打算让它测量完成2 ^ 32次迭代循环所需的时间,我预计大约需要1.48秒(4/2.7 = 1.48).

但实际上它只需要2毫秒,而不是1.48秒.我想知道这是否是下面任何JVM优化的结果?

public static void main(String[] args)
{
    long start = System.nanoTime();

    for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++){
    }
    long finish = System.nanoTime();
    long d = (finish - start) / 1000000;

    System.out.println("Used " + d);
}
Run Code Online (Sandbox Code Playgroud)

java jvm for-loop

113
推荐指数
5
解决办法
1万
查看次数

为什么"while(i ++ <n){}"明显慢于"while(++ i <n){}"

显然在我的Windows 8笔记本电脑上使用HotSpot JDK 1.7.0_45(所有编译器/ VM选项都设置为默认值),下面的循环

final int n = Integer.MAX_VALUE;
int i = 0;
while (++i < n) {
}
Run Code Online (Sandbox Code Playgroud)

比以下情况快至少2个数量级(~10 ms vs.~5000 ms):

final int n = Integer.MAX_VALUE;
int i = 0;
while (i++ < n) {
}
Run Code Online (Sandbox Code Playgroud)

在编写循环以评估另一个不相关的性能问题时,我碰巧注意到了这个问题.之间的差异++i < ni++ < n是巨大的,足以显著影响结果.

如果我们查看字节码,更快版本的循环体是:

iinc
iload
ldc
if_icmplt
Run Code Online (Sandbox Code Playgroud)

而对于较慢的版本:

iload
iinc
ldc
if_icmplt
Run Code Online (Sandbox Code Playgroud)

因此++i < n,它首先将局部变量递增i1,然后将其推入操作数堆栈,同时i++ < n以相反的顺序执行这两个步骤.但这似乎并不能解释为什么前者要快得多.后一种情况是否涉及临时副本?或者是否应该负责性能差异的字节码(VM实现,硬件等)以外的东西?

我已经阅读了一些关于++ii++(但并非详尽无遗)的其他讨论,但未找到任何特定于Java的答案,并且与价值比较中涉及++ii++涉及的情况直接相关.

java performance compiler-optimization pre-increment post-increment

74
推荐指数
3
解决办法
9556
查看次数

这是JVM错误还是"预期行为"?

我注意到了一些意想不到的行为(意外相对于我的个人期望),我想知道是否有什么东西,如果JVM中有一个错误,或者这可能是一个边缘情况,我不明白究竟是什么细节应该发生.假设我们在main方法中有以下代码:

int i;
int count = 0;
for(i=0; i < Integer.MAX_VALUE; i+=2){
  count++;
}
System.out.println(i++);
Run Code Online (Sandbox Code Playgroud)

一个天真的期望是,这将打印Integer.MAX_VALUE-1,最大甚至可表示int.但是,我认为整数算术应该在Java中"翻转",因此Integer.MAX_VALUE应该导致添加1 Integer.MIN_VALUE.由于Integer.MIN_VALUE仍然小于Integer.MAX_VALUE,循环将继续迭代负甚至整数.最终它会回到0,这个过程应该重复为无限循环.

当我实际运行此代码时,我得到非确定性结果.打印的结果往往大约为50万,但确切的值会有所不同.因此,当我认为它应该是一个无限循环时,不仅循环终止,而且它似乎随机终止.这是怎么回事?

我的猜测是,这可能是JVM中的一个错误,或者正在进行大量的时髦优化,这会产生这种预期的行为.这是什么?

java jvm integer-overflow compiler-optimization

70
推荐指数
2
解决办法
3719
查看次数

Java integer ++我没有改变这个值

我刚刚制作了这个简单的"程序":

public static void main(String[] args) {
        int i = 1;
        int k = 0;
        while (true) {
            if(++i==0) System.out.println("loop: " + ++k);
        }
    }
Run Code Online (Sandbox Code Playgroud)

运行此程序后,我立即得到输出:

(...)
loop: 881452
loop: 881453
loop: 881454
loop: 881455
loop: 881456
loop: 881457
loop: 881458
(...)
Run Code Online (Sandbox Code Playgroud)

好像i总是0.

事实上,当我在Eclipse中调试时,在暂停程序时,i总是为零.单步执行循环时,i会递增,但在恢复和挂起调试器时,i再次为0.

当我改变i为long时,在运行程序时我需要等待一段时间才能看到第一个loop: 1.在调试器中,在暂停程序时,i会增加:它不是0,所以它可以正常工作.

++i作为int有什么问题?

java

29
推荐指数
4
解决办法
2549
查看次数