0

第一种情况:

void lowTermReduction(int numerator, int denominator) {
    int gcd = GCD(numerator, denominator);
    numerator /= gcd;
    denominator /= gcd;
}

第二种情况:

void lowTermReduction(int numerator, int denominator) {
    int gcd = GCD(numerator, denominator);
    if (gcd != 1) {
        numerator /= gcd;
        denominator /= gcd;
    }
}

哪一个更高效(快速)?
在第一种情况下,函数总是执行除法,如果这个除法是 1 并且不改变 和 中的numeratordenominator。我不知道 CPU 在执行 12/1 还是 12/2 时是否更快,但我认为这完全一样。
相反,在第二种情况下,该函数在大公约数相差 1 时才进行除法。但在这种情况下,它执行的是逻辑运算if
有效率差异吗?如果是这样,它们是否相关?

4

5 回答 5

3

如果不对具有典型用例的具体 CPU 架构进行分析,很难说哪个更快。

但是让我们看一下这两个版本:

第一个版本:

  • 没有“如果”,因此将始终执行两个部门。
  • 此外,内存(或 CPU 寄存器)总是有两次读取和两次写入。

第二个版本:

  • 总是有一个比较操作,这也会导致一次内存读取(或 CPU 寄存器读取)
  • 但是,只有在“if”条件为真的情况下才会执行这两个除法。
  • 此外,如果满足条件,则再次进行两次读取和两次写入。

因此,实际上它取决于“if”条件为真的频率,而这又取决于用例。但是,总的来说,我会说第一个版本更快,因为大多数情况下,第二个替代方案中的“if”条件无论如何都会得到满足。因此,大多数情况下,您将获得一个比较操作和一个针对“if”条件的读操作,以及两个读和两个写操作,以及两个针对“if”块的除法操作。

于 2013-04-30T19:44:02.927 回答
2

答案取决于您通常会提供给函数的输入。如果大多数时候 GCD 最终为 1,那么第二个函数将执行更少的指令。如果大多数时候 GCD 最终不是 1,那么第一个函数将执行更少的指令。

此功能不太可能成为您系统的瓶颈。您应该分析您的整个系统,并且只优化真正花费最多时间的部分。

于 2013-04-30T19:36:20.217 回答
1

大多数计算机中的除法是 CPU 可以执行的最慢的算术运算之一,另一方面,条件跳转非常快(如果您现在忘记管道问题)。

但是,首先您需要弄清楚这是否真的是您程序中的瓶颈。然后,您需要测量两个版本的时间。

最后,我猜你不会看到任何性能提升,因为你将数字除以1,所以应该很快,而且你可能只会在此处引入跳转速度问题,因此if版本可能会变慢.

确保您阅读了比尔对此问题的回答。

于 2013-04-30T19:32:16.150 回答
0

因为第二个版本是在进行比较,所以第二个版本会比较慢。

问题是:慢多少?

我的猜测是时间改进并不显着。

如果你想加快程序,弄清楚如何摆脱分裂。

于 2013-04-30T19:38:46.870 回答
0

第一种情况平均会更快。原因是,第二个函数总是必须进行比较,然后在认为必要时进行除法。虽然如果只执行一次或两次你不会注意到差异,但如果它是一个更大的函数的一部分,它将运行多次,它可能会稍微更明显。

第一个在调用时总是执行 1 次操作,因此如果调用 n 次,它将执行 n 次操作。第二好的情况将执行 n 次操作(如果每个调用的 GCD 为 1),但最坏的情况将执行 2n 次操作。所以我会说安全的赌注是选择第一个案例

于 2013-04-30T19:34:15.223 回答