C++ 在C+中,向数字重复添加1比同时添加所有内容慢+;?

C++ 在C+中,向数字重复添加1比同时添加所有内容慢+;?,c++,C++,如果我有一个数字a,将1添加到b次会比简单地添加a+b慢吗 a += b; 或 for(int i=0;i < P>语言C++不描述这些操作中的任一个。编译器可以自由地将第一条语句转换为第二条语句,这是一种合法的编译方式 在实践中,许多编译器会将这两个子表达式视为同一个表达式,假设所有内容都是int类型。然而,第二个是脆弱的,因为看似无害的更改会导致性能大幅下降。“不重要”类型的微小变化、附近的额外语句等 第一个比第二个慢是极为罕见的,但是如果a的类型使得+=b的操作比多次调用+=1慢得多,则

如果我有一个数字a,将1添加到b次会比简单地添加a+b慢吗

a += b;

for(int i=0;i
我意识到第二个例子似乎有点傻,但我有一种情况,编码实际上会更容易,我想知道这是否会影响性能


编辑:谢谢你的回答。看起来有些海报想知道我的处境。我试图编写一个函数,将输入的字符转换为一定数量的字符(即密码),如果它是一个字母。所以,我想说一个字符+=移位数,但我还需要考虑ascii表中小写字符和大写字符之间的跳转,以及从z到A的换行。因此,虽然这在另一方面是可行的,我认为最简单的方法是一直添加一个字符,直到我到达一组字母字符的末尾,然后跳转到下一个字符并继续

如果你的循环真的那么简单,我看不出编译器为什么不能优化它。不过,我不知道是否真的会有。如果您的编译器不这样做,那么单次加法将比循环快得多。

是的,绝对慢。第二个例子太愚蠢了。我非常怀疑你有这样做的理由


假设“b”是500000。。。大多数计算机可以在一个操作中添加,为什么要做500000个操作(不包括循环开销)。< /P> < P>语言C++不描述这些操作中的任一个。编译器可以自由地将第一条语句转换为第二条语句,这是一种合法的编译方式

在实践中,许多编译器会将这两个子表达式视为同一个表达式,假设所有内容都是
int
类型。然而,第二个是脆弱的,因为看似无害的更改会导致性能大幅下降。“不重要”类型的微小变化、附近的额外语句等

第一个比第二个慢是极为罕见的,但是如果
a
的类型使得
+=b
的操作比多次调用
+=1
慢得多,则可能是这样。比如,

struct A {
  std::vector<int> v;
  void operator+=( int x ) {
    // optimize for common case:
    if (x==1 && v.size()==v.capacity()) v.reserve( v.size()*2 );
    // grow the buffer:
    for (int i = 0; i < x; ++i)
      v.reserve( v.size()+1 );
      v.resize( v.size()+1 );
    }
  }
};
结构A{ std::向量v; 无效运算符+=(整数x){ //针对常见情况进行优化: 如果(x==1&&v.size()==v.capacity())v.reserve(v.size()*2); //增长缓冲区: 对于(int i=0;i 然后
A;int b=100000;a+=b将比循环构造花费更长的时间


但是我必须努力工作。

与循环中的指令总数相比,在循环中增加变量的开销(CPU指令)可能微不足道(除非在循环中唯一要做的事情是增加)。循环变量可能保持在CPU缓存的较低级别(如果不在CPU注册表中),并且增量非常快,因为in不需要通过FSB从RAM读取。无论如何,如果有疑问,只需快速创建一个概要文件,您就会知道牺牲代码可读性来提高速度是否有意义。

如果处理器有一条递增指令,编译器通常会将“add one”操作转换为递增指令

一些处理器可能有一个优化的增量指令来帮助加速循环之类的事情。其他处理器可以将增量操作与加载或存储指令相结合

有一种可能性是,只包含递增指令的小循环可能会被乘法和加法替换。当且仅当功能相同时,才允许编译器这样做

这种操作通常会产生微不足道的结果。但是,对于大型数据集和性能关键型应用程序,这种操作可能是必要的,并且所获得的时间将非常重要

编辑1:
对于添加除1以外的值,编译器将发出处理器指令以使用最佳添加操作


添加操作在硬件上作为与递增不同的动物进行了优化。算术逻辑单元(ALU)已经存在很长时间了。基本的加法运算非常优化,比循环中的增量运算快得多

难道你不能在大约30秒内编写一个基准测试来测试这一点并告诉你它是否有任何区别吗?基本上,你已经有了代码。(一个循环总是要比一次加法花费更长的时间;多长时间取决于许多事情,包括编译器优化。性能差异是否有意义也取决于实际使用情况。)我认为,提及您的用例或编程上下文是很有用的,因为第二种形式比第一种更容易使用。做n次的事情通常会慢n倍,欢迎使用常识。此外,计算机并不真正关心值有多大,1+1的速度与1000000+1000000的速度一样快。这个循环非常简单,除非禁用优化,否则编译器应该生成与第一种情况类似的代码。如果您有实际情况,应该显示它(或者至少显示它的简化版本)。否则,你的问题是愚蠢的。“肯白,如果他问这个问题,他可能不知道如何使用定时器。”编译器可以自由地将你的第一个语句变成第二个“你不是说相反的吗?”DRoad。C++标准允许编译器编译<代码> A+= B < />到一个循环中,这个循环增加了代码> A<代码>:我的意思是这样。我没有提到另一方面。是的,它还允许他们将循环转换成一个简单的增量,但这个短语的要点是指向o
struct A {
  std::vector<int> v;
  void operator+=( int x ) {
    // optimize for common case:
    if (x==1 && v.size()==v.capacity()) v.reserve( v.size()*2 );
    // grow the buffer:
    for (int i = 0; i < x; ++i)
      v.reserve( v.size()+1 );
      v.resize( v.size()+1 );
    }
  }
};