当前位置: 首页 > 面试题库 >

Java好奇循环性能

楚茂实
2023-03-14
问题内容

我在评估我的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);
    }   
}

问题答案:

在第一种情况下,分支预测错误会降低性能。尽管第二种情况可以完成一些工作,但它有些直截了当,因此处理器可以轻松预测下一步。请参阅此Wikipedia页面以获取更多信息。

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



 类似资料:
  • 问题内容: 我尝试从0.1循环到2.0,然后将输出打印到控制台。但是我得到了如下奇怪的输出: 源代码: 为什么它不打印确切的数字而不是像点呢?另外,使用代替还有什么区别,因为我不知道如何增加0.1? 问题答案: 这是正常的。它是浮点型固有的;像0.3这样的数字不能作为精确值存储在二进制文件中,因此您会逐渐积累错误。参考资料: Python手册,Wikipedia,Princeton CS的技术说明

  • 问题内容: String s = “”; for(i=0;i<....){ s = some Assignment; } 要么 我不需要在循环外再次使用“ s”。第一个选项可能更好,因为不会每次都初始化一个新的String。但是,第二个结果将导致变量的范围仅限于循环本身。 编辑:回应米尔豪斯的回答。在循环中将String分配给常量是没有意义的吗?不,这里的“某些分配”是指从要迭代的列表中获得的变化

  • 如果我有下面的for循环: 我知道外环将迭代次,而内环将为每th从外环迭代一次。 因此,为了确定时间复杂度,我们有一些类似于 不确定如何继续并得到一个封闭形式的时间复杂度。

  • 我试图将我的编程风格从命令式切换到声明式,但有一些概念困扰着我,比如当涉及到循环时的性能。例如,我有一个原始数据,在操作它之后,我希望得到3个预期结果:itemsHash、namesHash、rangeItemsHash 为了达到预期的结果,命令式只循环一次,而声明式至少循环3次(、、)。哪一个比较好?在性能上有什么权衡吗?

  • 问题内容: 以下两个循环之间的性能差异(如果有)是什么? 和 问题答案: 版本1.5中引入的for-each循环通过完全隐藏迭代器或index变量,消除了混乱和出错的机会。结果成语同样适用于集合和数组: 当你看到冒号(:)时,将其读为“ in”。因此,上面的循环读为“对于元素中的每个元素e”。请注意,即使对于数组,使用for-each循环也不会降低性能。实际上,在某些情况下,它可能只比普通的for

  • 我试图在for循环中获得for循环,因此输出如下: 我希望输出显示一个正方形 我不知道它为什么不这样做。下面是我的代码: