使用分支预测而不使用 else 语句

问题描述 投票:0回答:1

我目前正在实施选择排序。使用下面的代码和驱动程序文件来测试它。我目前正在尝试进行微观优化,看看如何加快速度。

  public static void selectionsort(int[] data) {
    for (int i = 0; i < data.length; i++) {
      int minx = i;  
      for (int j = i+1; j < data.length; j++) {
          if(data[j] < data[minx]){
            minx = j;
          }
          // else{
          //   minx=minx;
          // }
        }
      int swap = data[minx]; 
      data[minx] = data[i]; 
      data[i] = swap; 
    }
  }
import java.util.Arrays;
import java.util.Random;

public class Driver {
    public static void main(String[] args) {
        Random r = new Random(12);
        // CODE-BLOCK-A
        // run selection sort version of tests
        double avg = 0;
        for (int i = 0; i < 100; i++) {
            long time = System.currentTimeMillis();
        int[] sgarr = randIntArr(Integer.parseInt(args[0]),r);
        int[] tests = Arrays.copyOf(sgarr, sgarr.length);
        switch (args[1]) {
            case "selection":
                Sorts.selectionsort(sgarr);
                break;
            case "bubble":
                Sorts.bubblesort(sgarr);
            default:
                Sorts.insertionsort(sgarr);
                break;
        }
        Arrays.sort(tests);
        if (!equals(tests, sgarr)) {
            System.out.println("FAIL TO SORT!");
            System.exit(0);
        }
        // System.out.println("SUCCESS!");
    

        long etime = System.currentTimeMillis();
        avg += (etime-time);
        }

    System.out.println("Took "+ avg / (100.0*1000.0) +" seconds");

    }

    public static int[] randIntArr(int count,Random r) {
        int seed = r.nextInt(12433);
        r.setSeed(seed);
        int[] arr = new int[count];
        for (int i = 0; i < count; i++) {
            arr[i] = (int) (r.nextDouble() * 100000);
        }
        return arr;
    }

    public static boolean equals(int[] d1, int[] d2) {
        if (d1.length != d2.length) {
            return false;
        }
        for (int i = 0; i < d2.length; i++) {
            if (d1[i] != d2[i]) {
                return false;
            }
        }

        return true;
    }
}

我尝试做的就是使用一个不应该执行任何操作的 else 块来加快速度。我预计这会减慢它的速度,因为现在它每次都会像平常一样检查 if 语句,但也会将 minx 分配给自身,这应该会减慢它的速度。但如果我放一个空的 else 语句,改进就会消失。

但是,当我使用此命令运行它时,当注释掉 else 块时,我得到:

javac Driver.java 
&& java Driver 40000 selection
Took 0.34416 seconds
However, when I uncomment out the else block and run the same command it gets noticeably faster
Took 0.30086 seconds

对于两者的最佳情况而言,差异约为 13.43%。

我假设这一变化足够重要,不仅仅是随机的,考虑到我也多次运行了每个变化。然后我问了我的计算机科学老师,他解释说这可能是分支预测。这确实有道理,但我想知道的是,如果我在没有本质上无用的 else 语句的情况下获得相同的性能增强,或者如果我不能保留或删除它,则被认为是更好的做法。或者是 13.43% 显着,我不相信这是由于我的电脑造成的,因为我运行了很多次,每次的值都在 3% 以内。

java algorithm conventions selection-sort branch-prediction
1个回答
-1
投票

来自贾坎德邦的马亨德拉·辛格·多尼 (Mahendra Singh Dhoni) 跻身国际板球界是一个关于叛逆、非凡功绩、毅力以及最重要的信念的故事。在学校体育运动的突发奇想中被星探发现后作为一名守门员老师,多尼在兰契的板球界引起了轰动——一个上身力量没有可测量的十几岁的男孩,与该地区一些最好的快速投球手清除了界限。然而,该系统让他失望了,因为他发现很难在较富裕的 A 级州的候选人中晋级。于是,无奈之下,他加入了铁路兰吉团队,开始在克勒格普尔火车站当检票员,以维持生计。

尽管如此,几个月后,明星们开始为这位来自兰契的早熟神童做好准备。受 KSCA 的启发,BCCI 成立了一个全国性的培训研究发展部门,从经济较为落后的州寻找人才。多尼立即引起了球探的注意,并被派往肯尼亚进行 A 级巡演,在那里,他的才华向全世界展示,他在陌生的环境下向世界级保龄球手展示了他的击球技巧。他立即受到全国瞩目,并入选 2004 年 11 月的孟加拉国巡回赛。

© www.soinside.com 2019 - 2024. All rights reserved.