'for'循环vs Qt的'foreach'在C++中

Aja*_*jay 48 c++ performance foreach qt for-loop

哪个更好(或更快),一个C++ for循环或foreachQt提供的运算符?例如,以下条件

QList<QString> listofstrings;
Run Code Online (Sandbox Code Playgroud)

哪个更好?

foreach(QString str, listofstrings)
{
    //code
}
Run Code Online (Sandbox Code Playgroud)

要么

int count = listofstrings.count();
QString str = QString();
for(int i=0;i<count;i++)
{
    str = listofstrings.at(i);
    //Code
}
Run Code Online (Sandbox Code Playgroud)

pax*_*blo 149

在大多数情况下,这无关紧要.

关于这种方法或该方法是否更快的StackOverflow上的大量问题,认为在绝大多数情况下,代码花费大部分时间等待用户做某事.

如果你真的关心,简介为自己和作用于你的发现.

但我认为你很可能会发现,只有在最激烈的数据处理工作中,这个问题才能解决.只有在处理大量元素时,差异可能只有几秒甚至更长时间.

让代码先运行.然后让它快速运行(并且只有在您发现实际性能问题时).

在完成功能之前花费时间进行优化并且可以正确分析,这主要是浪费时间.

  • 这个数字很久以前就过了笑话阶段.我们应该编写一个答案机器人,寻找"哪个更快"并自动回复:对其进行分析 (51认同)
  • 并不是说它真的适用于这个简单的例子,但我想说的是,"不正确的代码就像你可以得到的那样不优化". (21认同)
  • 请参阅http://stackoverflow.com/questions/771092/is-method-a-faster-than-method-b:让我们看看它是否存活:-) (2认同)

Par*_*tes 23

首先,我只想说我同意Pax,并且速度可能不会进入它.foreach基于可读性赢得了胜利,这在98%的情况下都足够了.

但是当然Qt的人已经调查了它并且实际上做了一些分析:http: //blog.qt.io/blog/2009/01/23/iterating-efficiently/

从中学到的主要教训是:在只读循环中使用const引用,因为它避免了临时实例的创建.无论您使用何种循环方法,它还使循环的目的更加明确.


Eva*_*ran 14

这没关系.可能的情况是你的程序很慢,这不是问题.但是,应该注意的是,你并没有做出完全相同的比较.Qt foreach更类似于此(此示例将使用QList<QString>):

for(QList<QString>::iterator it = Con.begin(); it != Con.end(); ++it) {
    QString &str = *it;
    // your code here
}
Run Code Online (Sandbox Code Playgroud)

宏可以通过使用一些编译器扩展(如GCC __typeof__)来获取传递的容器类型.还想象一下boost BOOST_FOREACH在概念上非常相似.

你的例子不公平的原因是你的非Qt版本正在增加额外的工作.

您正在编制索引而不是实际迭代.如果您使用的是具有非连续分配的类型(我怀疑可能是这种情况QList<>),那么索引将更加昂贵,因为代码必须计算第n个项目的"where".

话虽如此.它仍然没关系.如果存在的话,这两段代码之间的时间差异可以忽略不计.不要浪费你的时间担心它.写下你发现的更清晰易懂的内容.

编辑:作为奖励,目前我非常支持C++ 11版本的容器迭代,它简洁明了:

for(QString &s : Con) {
    // you code here
}
Run Code Online (Sandbox Code Playgroud)


小智 11

我不想回答更快的问题,但我想说哪个更好.

Qt的foreach最大的问题是它在迭代之前需要一个容器的副本.您可以说'这无关紧要,因为Qt类已被重新计算',但由于使用了副本,您根本不会实际更改原始容器.

总之,Qt的foreach只能用于只读循环,因此应该避免使用.Qt很乐意让你编写一个foreach循环,你认为它会更新/修改你的容器,但最后所有的变化都会被抛弃.


ymo*_*eau 8

由于Qt的5.7foreach宏已被弃用,QT鼓励您使用C++ 11 for来代替.
http://doc.qt.io/qt-5/qtglobal.html#foreach

(有关差异的更多详细信息,请访问:https://www.kdab.com/goodbye-q_foreach/)