Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java循环性能_Java_Performance_Random_For Loop - Fatal编程技术网

Java循环性能

Java循环性能,java,performance,random,for-loop,Java,Performance,Random,For Loop,我在评估java代码时遇到了一个大问题。为了简化这个问题,我编写了以下代码,这些代码产生了相同的奇怪行为。重要的是方法run()和给定的双值速率。对于我的运行时测试(在main方法中),我一次将速率设置为0.5,另一次将速率设置为1.0。值为1.0时,if语句将在每个循环迭代中执行,值为0.5时,if语句将执行一半。出于这个原因,我期望第一种情况下运行时间更长,但事实正好相反。 有人能解释我这种现象吗 主要研究结果如下: Test mit rate = 0.5 Length: 50000000,

我在评估java代码时遇到了一个大问题。为了简化这个问题,我编写了以下代码,这些代码产生了相同的奇怪行为。重要的是方法run()和给定的双值速率。对于我的运行时测试(在main方法中),我一次将速率设置为0.5,另一次将速率设置为1.0。值为1.0时,if语句将在每个循环迭代中执行,值为0.5时,if语句将执行一半。出于这个原因,我期望第一种情况下运行时间更长,但事实正好相反。 有人能解释我这种现象吗

主要研究结果如下:

Test mit rate = 0.5
Length: 50000000, IF executions: 25000856
Execution time was 4329 ms.
Length: 50000000, IF executions: 24999141
Execution time was 4307 ms.
Length: 50000000, IF executions: 25001582
Execution time was 4223 ms.
Length: 50000000, IF executions: 25000694
Execution time was 4328 ms.
Length: 50000000, IF executions: 25004766
Execution time was 4346 ms.
=================================
Test mit rate = 1.0
Length: 50000000, IF executions: 50000000
Execution time was 3482 ms.
Length: 50000000, IF executions: 50000000
Execution time was 3572 ms.
Length: 50000000, IF executions: 50000000
Execution time was 3529 ms.
Length: 50000000, IF executions: 50000000
Execution time was 3479 ms.
Length: 50000000, IF executions: 50000000
Execution time was 3473 ms.
代码

public ArrayList<Byte> list = new ArrayList<Byte>();
public final int LENGTH = 50000000;

public PerformanceTest(){
    byte[]arr = new byte[LENGTH];
    Random random = new Random();
    random.nextBytes(arr);
    for(byte b : arr)
        list.add(b);
}

public void run(double rate){

    byte b = 0;
    int count = 0;

    for (int i = 0; i < LENGTH; i++) {

        if(getRate(rate)){
            list.set(i, b);
            count++;
        }
    }
    System.out.println("Length: " + LENGTH + ", IF executions: " + count);
}

public boolean getRate(double rate){
    return Math.random() < rate;
}

public static void main(String[] args) throws InterruptedException {
    PerformanceTest test = new PerformanceTest();

    long start, end;
    System.out.println("Test mit rate = 0.5");
    for (int i = 0; i < 5; i++) {
        start=System.currentTimeMillis();
        test.run(0.5);
        end = System.currentTimeMillis();
        System.out.println("Execution time was "+(end-start)+" ms.");

        Thread.sleep(500);
    }       
    System.out.println("=================================");
    System.out.println("Test mit rate = 1.0");      
    for (int i = 0; i < 5; i++) {
        start=System.currentTimeMillis();
        test.run(1.0);
        end = System.currentTimeMillis();
        System.out.println("Execution time was "+(end-start)+" ms.");
        Thread.sleep(500);
    }   
}
public ArrayList list=new ArrayList();
公共最终整数长度=50000000;
公共绩效测试{
字节[]arr=新字节[长度];
随机=新随机();
随机下字节(arr);
for(字节b:arr)
列表.添加(b);
}
公共无效运行(双倍费率){
字节b=0;
整数计数=0;
for(int i=0;i
在第一种情况下,分支预测失误会导致性能下降。虽然第二种情况做了一些工作,但它有点直截了当,所以处理器可以很容易地预测下一步。更多信息请参见此


尝试使用0.7进行测试。如果我是正确的,那么性能将介于0.5和1.0之间。

与非常相似,并且在幕后也有相同的原因。

为了确认您看到了分支预测失误的影响,我运行了一些测试。表显示了速率(运行方法的输入)、执行的
if
数和运行时间

0.0   0             1162
0.1   5,000,892     1204.25
0.2   10,002,410    1236.8
0.3   14,998,226    1264
0.4   19,996,983    1278
0.5   24,998,455    1305.5
0.6   29,998,879    1263.25
0.7   34,999,821    1232.25
0.8   39,999,414    1203.5
0.9   44,998,674    1202
1.0   50,000,000    1176.75
越接近0.5,分支错误预测就越多(大约每次运行一次)。越接近0或1,分支预测就越准确(速率为0或1时没有预测失误)

因为一幅画胜过千言万语:


可能与此有关。Random在这里相当慢。我建议你遵循一个简单的级数,这样你就不会把大部分时间花在生成随机数上。我建议您交替进行测试,而不是多次运行一个测试,多次运行第二个测试。(你不需要在它们之间睡觉)在热身时思考如果你先执行1.0?或预生成一个你不需要计时的随机数数组会怎么样-几乎完全将其作为一个因子从结果中移除。Math.random()保证<1.0情况下的速率,因此,处理器可以很容易地预测分支的方式。第二种情况更快,分支错误预测对第一种情况的影响似乎大于第二种情况。@NominSim你说得对,我写的是第二种情况,而不是第一种情况,现在已经修复了。好的。。。这似乎就是原因。你很棒,非常感谢。