++我或我++的for循环?
可能重复:
在C ++中,i ++和++ i之间有性能差异吗?
有没有什么原因,一些程序员写的++i
在一个正常的循环,而不是写i++
?
对于整数,前后增量没有区别。
如果i
是一个非平凡的类的对象,那么++i
一般是首选,因为对象被修改,然后评估,而i++
修改后评估,所以需要复制。
++i
由于其语义, ++i
效率略高一些:
++i; // Fetch i, increment it, and return it i++; // Fetch i, copy it, increment i, return copy
对于整型指数,效率增益最小(如果有的话)。 对于迭代器和其他较重的对象来说,避免这个副本可能是一个真正的胜利(特别是如果循环体不包含太多的工作)。
作为一个例子,考虑使用一个理论上的BigInteger类来提供任意的精度整数(以及某种向量types的内部)的下面的循环:
std::vector<BigInteger> vec; for (BigInteger i = 0; i < 99999999L; i++) { vec.push_back(i); }
我的++操作包括一个循环的拷贝构造(即操作符new,逐位拷贝)和销毁(operator delete),除了实质上再创build一个索引对象的副本外, 基本上你已经把要完成的工作加倍了(并且最有可能增加内存碎片),只要使用后缀增量就可以了,前缀已经足够了。
++i
是一个预增量; i++
是后增量。
后增量的缺点是它会产生一个额外的值; 它会在修改i
时返回旧值的副本 。 因此,你应该尽可能避免它。
整数,这是首选。
如果循环variables是一个类/对象,它可以有所作为(只有分析可以告诉你,如果它是一个重大的差异),因为后增量版本要求您创build该对象的副本被丢弃。
如果创build这个副本是一个昂贵的操作,那么您每次通过循环都要花费一次,没有任何理由。
如果你养成了习惯于循环使用++i
的习惯,那么你就不需要停下来思考在这个特定情况下你所做的是否有意义。 你一直都是。
这是有原因的:performance。 我++生成一个副本,这是一个浪费,如果你立即丢弃它。 当然,编译器可以优化掉这个副本,如果i
是一个原始的,但它不能。 看到这个问题。
没有一个编译器在盐中的重量会在两者之间运行不同
for(int i=0; i<10; i++)
和
for(int i=0;i<10;++i)
++我和我++有相同的成本 。 唯一不同的是++ i的返回值是i + 1,而i ++的返回值是i。
所以对于那些喜欢++我,可能没有任何有效的理由,只是个人喜好。
编辑:这是错误的类,正如在其他职位所述。 如果我是一个类,i ++将会生成一个副本。
正如其他人已经指出的那样,对于用户定义的types,预增量通常比后增量更快。 为了理解为什么这样,看看典型的代码模式来实现这两个操作符:
Foo& operator++() { some_member.increase(); return *this; } Foo operator++(int dummy_parameter_indicating_postfix) { Foo copy(*this); ++(*this); return copy; }
正如你所看到的,前缀版本只是修改对象并通过引用返回它。
另一方面,后缀版本必须在执行实际增量之前进行复制,然后将该副本按值复制callback用方。 从源代码中可以看出,后缀版本必须做更多的工作,因为它包含对前缀版本的调用: ++(*this);
对于内置types,只要丢弃该值,就不会有任何区别,即只要不将++i
或i++
embedded到较大的expression式中,如a = ++i
或b = i++
。
个人喜好。
通常。 有时候这很重要,但不要在这里performance得像一个混蛋,但如果你不得不问,那可能不会。
当你使用postfix时,它会在内存中的更多对象上实例化。 有人说在for循环中使用后缀运算符更好