【问题标题】:if (n!=0) n=0; v/s n=0; Which is more efficient and why? [closed]如果 (n!=0) n=0; v/s n=0;哪个更有效,为什么? [关闭]
【发布时间】:2020-03-06 01:53:45
【问题描述】:

作为高级程序员键入程序时,n = 0; 看起来更高效、更简洁。

但是n = 0; 真的比if (n != 0) n = 0; 更有效率吗?

  1. n 更有可能是0

  2. n 不太可能是0

  3. n 绝对不确定时。

语言:C (C90)

编译器:Borland 的 Turbo C++

最少的可重现代码

void scanf();

void main()
{
int n; // 2 bytes

n=0; // Expression 1

scanf("%d",&n); // Absolutely uncertain

if(n!=0) n=0; // Expression 2

}

注意:我上面提到的代码仅供您参考。请不要随波逐流。

如果您对上述语言/标准/编译器不满意,请随时用您喜欢的语言/标准/编译器解释上述 3 种情况。

【问题讨论】:

  • 用什么编译器?在哪些系统上?对于哪种类型的n?这太宽泛了,无法回答,而且几乎可以肯定在 99.999% 的情况下不值得担心。只需输入n = 0; 并继续担心实际有用的事情。 Fwiw,就我个人而言,我怀疑分支是否比重新分配相同值所带来的任何微小损失更便宜。
  • 这样想,无论你选择哪一个,它总是需要至少一个指令(比较或存储),所以......
  • 该问题没有minimal reproducible example
  • 这两个程序是否具有相同的外部行为,我们无法判断。如果它们具有相同的行为,它们可以产生相同的机器代码。如果它们不相同,那么其中一个可能比另一个更快...
  • 这个问题的答案取决于类型和改变功能的因果关系。太宽泛

标签: c if-statement variables machine-code low-level-code


【解决方案1】:

如果n是2的补码整数类型或者无符号整数类型,那么直接写n = 0肯定不会比有条件检查的版本慢,一个好的优化编译器会生成同样的代码。一些编译器将赋值编译为零作为寄存器值与自身进行异或,这是一条指令。

如果n 是浮点类型、1s' 补码整数类型或有符号幅度整数类型,则两个代码 sn-ps 的行为不同。例如。例如,如果n 的符号为负零。 (确认@chqrlie。)另外,如果n 是系统上的一个指针而不是多个空指针表示,那么if (n != 0) n = 0; 将不会分配n,当n 是各种空指针。 n = 0; 赋予了不同的功能。

“将永远更有效率”是不正确的。应该读n成本低,写n成本高(想想重写非易失性内存需要重写一个页面)并且很可能n == 0,那么n = 0;比较慢, 效率低于if (n != 0) n = 0;

【讨论】:

  • 您提出了一个关于浮点类型的好观点,但您的示例不正确:如果nNaNn != 0 将为真(因为n == 0 将为假)。如果n 为负零,则两个代码 sn-ps 不同的情况:n = -0.0;
  • @chqrlie:已经很晚了!好点,我偷了它。
  • 为了完整起见,我们可以补充一点,负零的行为不仅限于浮点类型,在不太可能的架构上,整数使用一个补码或符号/大小来表示......另一个特殊情况考虑是否将n 定义为volatile。写入它可能会产生不必要的副作用。
  • @chux-ReinstateMonica:现在是 wiki 的时候了 - 请在闲暇时添加贡献。
  • @NephewofStackoverflow:我一直有这样的印象,是的,尽管显然 ARM64 并非如此
【解决方案2】:

n = 0;

由于没有条件检查,效率总是更高。

https://godbolt.org/z/GEzfcD

【讨论】:

  • 哼。奇怪的是它生成r3, #0。最好把我的 most 改成 many
  • @Bathsheba ARM xor 比立即加载慢。
  • 不,这个答案是错误的。如果你的 COW 页面为零,那么它会更慢。
  • @AnttiHaapala 评论错误。只有当尚未创建 COW 对象并且您写入的位置为零时,您的评论才有意义。并且仅在 first 写入时会变慢。所以在正常情况下,99.99% 的写入速度会更快。 BTW const COW 对象没有实际意义
  • @old_timer 我可以举个例子说明什么时候相等吗?
猜你喜欢
  • 2020-03-19
  • 1970-01-01
  • 2020-08-31
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
  • 2012-12-10
  • 2019-01-06
  • 1970-01-01
相关资源
最近更新 更多