【问题标题】:What is recommended ++ or +1 in C++?在 C++ 中推荐的 ++ 或 +1 是什么?
【发布时间】:2017-06-01 07:08:11
【问题描述】:

S++S=S+1,可以推荐将值加1,为什么?

我认为S++ 应该是首选,因为它在内部是单机器指令 (INC)。如果我错了,请纠正我。其他方式我认为两者都是相同的,除了 ++ 是一元的,并且两者的后增量和运算符重载不同。

C# 有什么不同吗?

【问题讨论】:

  • 别忘了S+=1
  • 以上都不是。如果您想将一个值增加1 并且不关心之前的值,请使用++S
  • 老实说,我只在for 循环中使用++ 运算符,在几乎任何其他情况下都使用+= 运算符(在这两种语言中,即使我主要使用C#)。在几乎每个应用程序中,这都不会成为瓶颈,所以我不关心这种“优化”。但我确实关心可读性。
  • 为什么?因为这些是您想要传达的精确语义。
  • @PaulF:调试器在调试版本中使用时最有价值。调试版本通常禁用优化,因此您不会看到最终发布的代码。此外,您应该首先优化可读性,并处理性能、何时何地很重要。

标签: c# c++ c++11 visual-c++


【解决方案1】:

您永远不应该尝试进行如此微小的优化。现代编译器足够聪明,几乎可以为所有 3 个选项(++ii+=1i=i+1)生成相同的汇编代码。

是的,有时您可以获得一些微小的性能提升,例如,对于具有非常复杂的 ++ 运算符的某些类使用前缀 ++ 而不是后缀,但在绝大多数情况下,您的程序的一部分需要花费最多时间不是增量,因此要获得一些真实的结果,您应该在真实(或接近真实的)测试中分析您的代码,并找到不太有效的常用代码片段。

此外,还有一个更重要的事情需要考虑 - 代码可读性。在绝大多数情况下,它比性能更重要,而且只有在对时间要求最严格的代码片段中,我们才能牺牲可读性来换取性能(即使在这种情况下,也并非总是如此!有时添加更多硬件会更好)。

因此,我的建议是使用以最清晰的方式表达您的想法的选项

【讨论】:

  • 但是如果我对一些复杂的数据类型这样做,它会影响性能。
  • @viveknuna 是的,如果它涉及热路径,即在您的应用程序生命周期内执行最多的代码部分
  • @viveknuna:如果您对数据类型执行此操作,定义了它自己的增量运算符,则无论如何您都无法将++SS=S+1 进行对比。他们可能会做不同的事情,而后者甚至可能不合法。
  • 谁能解释一下机器指令?
  • @ChuckWalbourn 你说得对,如果迭代器通过除前缀 ++ 之外的任何其他方法递增,许多静态代码分析器也会警告非最佳代码。
【解决方案2】:

回到过去的美好时光,这种事情有所作为。我曾经查看生成的机器代码,然后调整 C 源代码以获得额外 10% 的速度提升。

没有了。您无法通过查看机器代码来预测速度。

  • 如今的许多优化都是在 CPU 中完成的。
  • IL 代码在运行时再次针对运行它的处理器进行优化,因此作为开发人员,您永远无法看到执行的指令。
  • CPU 速度如此之快,这几乎无关紧要。

您可以尝试测试不同的递增方式,看看哪种方式更快。一旦你对此感到厌烦,就不要再担心速度了,而是专注于编写清晰、无错误的代码。

【讨论】:

  • 现在的许多优化都是在 CPU 中完成的。 不,代码生成仍然是由软件完成的,它取决于智能编译器来发出相同的 asm对于i++,对于++ii = i + 1。但幸运的是,编译器 很聪明。此外,如果您知道自己在做什么,您仍然可以查看 asm 并预测速度。乱序执行 CPU 的静态分析不同于旧的有序机器,而是still possible for simple loops or blocks.
【解决方案3】:

C++ 同时拥有pre and post-increment operators
正如已经回答的here,预增量运算符通常更快。
(主要是因为编译器可以更好地优化它,并且不需要返回旧值的临时副本)。

【讨论】:

  • 这仅适用于具有重载增量运算符的类类型,这些运算符没有完全内联并优化任何复制。对于原始整数类型,通常没有区别。所以你可以说“预增量至少一样快”,或者“不慢”。或者后增量可以变慢。
  • 预增量可以慢一些。
【解决方案4】:

在通过 s = s + 1 OR s++ 递增变量 s 之间,我们首先需要接受该操作本身非常基本、简单和直接。我们基本上是将存储在变量中的值增加一个固定数字。尽管 s++ 比 s = s + 1 执行得更快,但这两种不同方法之间的时间差是相同的。 我尝试了以下代码:

    int s = 1;
    s++;

它给出了以下编译和执行时间:

编译时间:0.32 秒,绝对运行时间:0.14 秒,cpu 时间:0 秒,内存峰值:3 Mb,绝对服务时间:0.46 秒

之后,我尝试了以下代码:

    int s = 1;
    s = s + 1;

它给出了以下执行时间:

编译时间:0.32 秒,绝对运行时间:0.14 秒,cpu 时间:0 秒,内存峰值:3 Mb,绝对服务时间:0.46 秒

所以,正如我所说,这两个操作之间没有显着差异,因为它们本身非常简单。确实存在时差;但是,上面给出的执行时间并不是那么具体,这意味着必须存在 >0.001 的时间差,这几乎可以忽略不计。希望这能回答您的问题。

【讨论】:

  • 如果您在启用优化的情况下进行编译,则常量传播将使两者都等效于int s = 2;(如果您没有对其进行任何其他操作,则将其优化掉)。如果您在禁用优化的情况下编译,您的结果将毫无意义(并且可能是内存中循环计数器延迟的瓶颈,而不是为这些语句发出的任何 asm)。使用-O0 进行基准测试并不能深入了解-O3 的性能,对于像这样的微优化。 C loop optimization help for final assignment.
【解决方案5】:

++ 更强大。 你可以做这样的事情

if(a++ > 7) b=0;

【讨论】:

  • 在混淆代码方面更强大。几乎不是一个理想的目标。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-05
  • 1970-01-01
  • 2019-04-06
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
相关资源
最近更新 更多