C++ (插入排序使用';而';)和(插入排序使用';for';)之间的计算时间有什么区别? ///////////////////////////////////////////////////////////// 无效插入\u排序\u f(int*A,int s,int e){ int j,i,tmp; 对于(j=s+1;j=0&&A[i]>tmp;i--) A[i+1]=A[i]; A[i+1]=tmp; } } 无效插入\u排序\u w(int*A,int s,int e){ int j,i,tmp; 对于(j=s+1;j=0&&A[i]>tmp){ A[i+1]=A[i]; } A[i+1]=tmp; } } //////////////////////////////////////////////////////////////

C++ (插入排序使用';而';)和(插入排序使用';for';)之间的计算时间有什么区别? ///////////////////////////////////////////////////////////// 无效插入\u排序\u f(int*A,int s,int e){ int j,i,tmp; 对于(j=s+1;j=0&&A[i]>tmp;i--) A[i+1]=A[i]; A[i+1]=tmp; } } 无效插入\u排序\u w(int*A,int s,int e){ int j,i,tmp; 对于(j=s+1;j=0&&A[i]>tmp){ A[i+1]=A[i]; } A[i+1]=tmp; } } //////////////////////////////////////////////////////////////,c++,c,sorting,C++,C,Sorting,我用100000个数据测试了两个插入排序,一个使用“for”,另一个使用“while”。 我想在计算时间上没有什么有意义的区别。 但“while”比“for”平均速度快约1000毫秒。 这是哪一个造成的 附言。 我发布完整的解释代码 如果将功能更改为: void insertion\u sort\u w(int*A,int s,int e){ int j,i,tmp; 对于(j=s+1;j=0&&A[i]>tmp){ A[i+1]=A[i]; --一,; } A[i+1]=tmp; } } c

我用100000个数据测试了两个插入排序,一个使用“for”,另一个使用“while”。 我想在计算时间上没有什么有意义的区别。 但“while”比“for”平均速度快约1000毫秒。 这是哪一个造成的

附言。
我发布完整的解释代码

如果将功能更改为:

void insertion\u sort\u w(int*A,int s,int e){
int j,i,tmp;
对于(j=s+1;j=0&&A[i]>tmp){
A[i+1]=A[i];
--一,;
}
A[i+1]=tmp;
}
}
clang和gcc将为这两种方法生成相同的输出

对于最初的实现,为两种方法生成的ASM之间的差异是最小的。如果(在启用优化的情况下!)两者之间有任何显著的性能差异,我会非常惊讶

仔细看一下ASM:

您的while循环版本确实会产生更少的ASM,但这并不意味着它会更快。这只意味着编译器在for循环版本中生成了一些额外的代码块和跳转。这实际上可能会使for循环版本稍微快一点,因为它可能有一个while循环版本没有的额外的早期输出。另外,额外的跳跃可能是一个问题


使用vtune之类的分析器可能是了解相对性能的最佳选择。

我可以看到一些可能影响代码实际执行时间的因素。除非你是在编写特定于硬件的实时代码,否则我不会忽略性能上的差异

  • 编译器优化
    分解循环可以通过使用进行优化。编译器可能会对其中一种循环类型更有效地执行此操作
  • CPU优化
    在流水线CPU中,分支会损害性能。如果查看为“for”或“while”循环生成的汇编代码,您将有一个条件分支命令(执行另一个迭代或在循环后继续编码)。简单地说,CPU不想等待条件分支的结果来执行下一个命令,因此它“猜测”下一个命令,然后决定是否放弃该结果(读取和)。
    老实说,我不知道预测在一个循环或另一个循环中是否更有效,但这在理论上会有所不同
    您是否在启用编译器优化的情况下进行测试?我做了一些快速测试,两个功能之间没有明显的区别。@blastfurny哦,你说得对!我将“debug”改为“release”,所以计算时间没有差别。谢谢~但我还是不知道在“调试”模式下有什么不同。调试==“故意减速”。在调试构建中,每次修改变量时,它都会从寄存器中获取值,并将其写入内存位置。这使得调试器只需查看内存地址即可找到变量的当前值。在调试模式下,编译器不会刻意优化(例如,删除不必要的操作,重新排序以获得性能)。如果您准确地写下代码所表示的操作序列,您将看到这两个代码示例所做的事情是不同的,即使它们对函数的调用方具有相同的净效果。我的“while”比别人快。你和我的“for”速度一样,我不相信你。您是在启用优化的情况下编译,还是正在生成调试生成?调试模式。我发布我的完整代码。我在VisualStudio中做了默认设置。
    /////////////////////////////////////////////////////////////
    void insertion_sort_f(int *A, int s, int e) {
        int j, i, tmp;
        for (j = s+1; j < e; j++) {
            tmp = A[j];     
            for (i = j - 1; i >= 0 && A[i] > tmp; i--)
                A[i+1] = A[i];          
            A[i + 1] = tmp;
        }
    }
    void insertion_sort_w(int *A, int s, int e) {
        int j, i, tmp;
        for (j = s + 1; j < e; j++) {
            tmp = A[j];
            i = j;
            while (--i >= 0 && A[i] > tmp) {
                A[i + 1] = A[i];
            }
            A[i + 1] = tmp;
        }
    }
    //////////////////////////////////////////////////////////////