递增迭代器:“它比它更高效吗”?

发布于 2024-07-25 15:06:43 字数 613 浏览 2 评论 0原文

可能的重复:
i++ 和 ++ 之间是否存在性能差异我在 C++ 中?

我正在编写一个程序,其中使用迭代器循环遍历 std::vector。 有人告诉我,在 for 语句中执行 ++it 可以提高代码效率。 换句话说,他们是在说:

for ( vector<string>::iterator it=my_vector.begin(); it != my_vector.end(); ++it )

跑得比别人快

for ( vector<string>::iterator it=my_vector.begin(); it != my_vector.end(); it++ )

这是真的吗? 如果是,效率提升的原因是什么? 它 ++/++ 所做的只是将迭代器移动到向量中的下一项,不是吗?

Possible Duplicate:
Is there a performance difference between i++ and ++i in C++?

I am writing a program where an iterator is used to loop through a std::vector. Somebody told me that doing ++it in the for statement leads to more efficient code. In other words, they are saying that:

for ( vector<string>::iterator it=my_vector.begin(); it != my_vector.end(); ++it )

runs faster than

for ( vector<string>::iterator it=my_vector.begin(); it != my_vector.end(); it++ )

Is this true? If it is, what is the reason behind the efficiency improvement? All it++/++it does is move the iterator to the next item in the vector, isn't it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

匿名。 2024-08-01 15:06:44

it++ 有可能创建一个临时副本。

另外,在 C++ 中,有人可能会重载后递增运算符。

与预增量相比,这两件事都可能会降低性能。 在实践中,这两者都不重要。 尤其是临时副本,将被大多数编译器优化掉,因为 For 循环的第三个表达式没有副作用。

There is a chance that it++ will create a temporary copy.

Also, in C++, there is a chance that someone has overloaded the postincrement operator.

Both of these things could decrease performance vs preincrement. Neither is likely to matter in practice. The temporary copy, in particular, will be optimized away by most compilers since there are no side effects in the 3rd expression of your For loop.

情深已缘浅 2024-08-01 15:06:44

是的 ++ 它更高效,因为它 ++ 需要返回对象的副本然后递增自身。

yes ++it is more efficient because it++ need to return a copy of the object then increment itself.

溇涏 2024-08-01 15:06:44

是的。 据我记得,++it比it++更高效,因为it++创建了一个临时对象,而++it则没有。

Yes. As far as I remember, ++it is more efficient than it++, because it++ creates a temporary object, while ++it does not.

甜是你 2024-08-01 15:06:43

预增量更快的原因是后增量必须复制旧值才能返回。 正如 GotW #2 所说,“预增量比后增量更有效,因为对于后增量对象必须递增自身,然后返回一个包含其旧值的临时值,即使对于 int 这样的内置函数也是如此。”

GotW #55 提供了后增量的规范形式,这表明它必须执行前增量加上还有更多工作:

T T::operator++(int)
{
  T old( *this ); // remember our original value
  ++*this;        // always implement postincrement
                  //  in terms of preincrement
  return old;     // return our original value
}

正如其他人所指出的,某些编译器在某些情况下可能会对此进行优化,但如果您不使用返回值,那么最好不要依赖此优化。 此外,对于具有简单复制构造函数的类型,性能差异可能非常小,尽管我认为在 C++ 中使用预自增是一个好习惯。

The reason behind the preincrement being faster is that post-increment has to make a copy of the old value to return. As GotW #2 put it, "Preincrement is more efficient than postincrement, because for postincrement the object must increment itself and then return a temporary containing its old value. Note that this is true even for builtins like int."

GotW #55 provides the canonical form of postincrement, which shows that it has to do preincrement plus some more work:

T T::operator++(int)
{
  T old( *this ); // remember our original value
  ++*this;        // always implement postincrement
                  //  in terms of preincrement
  return old;     // return our original value
}

As others have noted, it's possible for some compiler to optimize this away in some cases, but if you're not using the return value it's a good idea not to rely on this optimization. Also, the performance difference is likely to be very small for types which have trivial copy constructors, though I think using preincrement is a good habit in C++.

养猫人 2024-08-01 15:06:43

它不太可能对向量产生任何影响。

一般来说,++it 极不可能比 it++ 慢(假设实现合理,如果它们重载),而且可能会更快。 原因是,如果迭代器类本身非常复杂,那么由于 it++ 必须在 it 递增之前返回值,因此实现通常会进行复制。

向量迭代器可能“只是指针”(在优化的非调试版本中),并且两个 operator++ 都将被内联。 由于未使用返回值,因此通常会忽略该副本。 所以这不会有任何区别。 我习惯于输入 ++it 因为:

1) 有一天它可能会对某些迭代器类型产生影响,并且我不想为该类型做一些特殊的事情。

2)我个人认为前缀运算符更清楚地表达了意图:“递增它”,而不是“使用它然后递增”。

It's unlikely to make any difference for a vector.

In general, ++it is extremely unlikely to be slower than it++ (assuming a sensible implementation, if they're overloaded), and just might be faster. The reason is that if the iterator class itself is at all complex, then because it++ has to return the value before it is incremented, the implementation will generally make a copy.

Vector iterators are probably "just pointers" (in optimised, non-debug builds), and both operator++s will be inlined. Since the return value is unused the copy will typically be elided. So it won't make any difference. I'm in the habit of typing ++it because:

1) Some day it might make a difference, for some iterator type, and I don't want to have to do something special for that type.

2) Personally I think the prefix operator more clearly expresses the intent: "increment it", as opposed to "use it and then increment".

红颜悴 2024-08-01 15:06:43

it++ 执行以下操作:

  1. 创建 it 的副本
  2. 增量 it
  3. 返回原始(非增量)it

++it 执行以下操作:

  1. increment it
  2. return it

因为 it++ 创建了一个副本,所以可以说变得“慢一点”。 然而,任何像样的编译器都会针对大多数定义的类型优化这种差异。 对于某些用户定义的类型,它可以更快。

it++ performs the following operations:

  1. create a copy of it
  2. increment it
  3. return the original (non-incremented) it

++it performs the following operations:

  1. increment it
  2. return it

Because it++ creates a copy, it can be said to be "slower". However, any decent compiler will optimize this difference out for most defined types. For some user-defined types it can be faster.

醉生梦死 2024-08-01 15:06:43

有时候是。 对于某些,它会被优化并保持不变。 对于 std::vector<> (和其他标准迭代器)它很可能会被优化为相同。

Sometimes yes. With some it will be optimized away and be the same. For std::vector<> (and other std-iterators) it will most likely be optimized to be the same.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文