Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 循环变量临时变量c++;_C++_Loops_Optimization_Temporary - Fatal编程技术网

C++ 循环变量临时变量c++;

C++ 循环变量临时变量c++;,c++,loops,optimization,temporary,C++,Loops,Optimization,Temporary,我发现了很多关于循环不变值以及是否在循环外声明它们的讨论。这不是我所关心的。我关心循环变量值,以及显式声明它们是否有任何潜在的性能影响 一位同事最近发出了一段代码。假设T是一个整数序列,可以是列表、向量等 #include <time.h> #include <algorithm> template <typename T> clock_t _check(T &cont, int cnt) { clock_t starttime = cloc

我发现了很多关于循环不变值以及是否在循环外声明它们的讨论。这不是我所关心的。我关心循环变量值,以及显式声明它们是否有任何潜在的性能影响

一位同事最近发出了一段代码。假设T是一个整数序列,可以是列表、向量等

#include <time.h>
#include <algorithm>

template <typename T>
clock_t _check(T &cont, int cnt)
{
    clock_t starttime = clock();

    srand(27);
    while (cnt--)
    {
        int cur = (rand() << 10) | rand();
        cont.insert(std::find_if(cont.begin(), cont.end(), [cur](int i) { return i >= cur; }), cur);
    }
    return clock() - starttime;
}
所以基本上,我会通过引用捕获cur,将行分为两部分,还有一些细微的格式差异。我不认为有任何潜在的性能下降作为参考,但让我知道,如果我错了。迭代器呢?我更喜欢这个,因为我认为它更清楚地说明了这个过程,但我是无意中又做了一次临时的优化还是剥夺了优化机会

我知道你们将要说什么,配置文件,不要过早优化。我知道,我相信。问题是我经常遇到在循环中声明临时变量的情况,而该变量可能不是迭代器。如果它是一个指针,或者某个需要深度拷贝的数据结构,该怎么办?如果函数调用通过引用const vs value得到这个变量,该怎么办?如果能对理论含义有所了解,我会很高兴,这样我就可以立即“以正确的方式”完成,而不必一直进行测试

那么,在使用临时变量之前显式声明它们有什么不利之处吗?还是编译器使这两个完全等效?也许人们喜欢第一个例子是一行,而我的是五行


编辑:我忘了解释我为什么想到这个。Sutter和Alexandrescu的“C++编码标准、101条规则、指导方针和最佳实践”在第9项中说,“减少对象的虚假临时副本,特别是在内部循环中,如果这样做不会影响代码的复杂性,这不是一种过早的优化”。这就是他们所说的吗?

您的问题的答案是,如果临时变量的复制构造函数很长(例如,复制矩阵或图像),并且无法进行优化(使用内联),则可能会影响性能

您的第二个示例调用

   std::find_if
   T::iterator copy constructor
   insert
   std::find_if
   insert
您的第一个示例调用

   std::find_if
   T::iterator copy constructor
   insert
   std::find_if
   insert

在您的特定示例中,两者之间的性能差异可能可以忽略不计。但是,您可以创建一个类似的示例,其中图像可能很棒。

一般来说,对于“足够好”的编译器,您可以引入一个命名的局部变量来替代临时编译器,而不会影响性能

如果你能让自己确信,通过引入一个命名的局部变量,你仅仅是在说明编译器到底要做什么,那么编译器将(应该)生成完全相同的代码

很明显,这是有限制的。命名的局部变量应该具有相同的生存期,这样就可以将其保存在寄存器中,而不必强制刷新到内存位置。有些情况下,编译器被允许删除(或内联)某些操作,您的替换不应阻止它这样做

在这种情况下,我相信迭代器只是指向集合的指针,因此它应该满足这些限制条件。可能还有其他情况并非如此


在这一点上,我应该要求简洁。一些程序员更喜欢冗长,因为他们相信代码越多,阅读就越容易。我不同意这种观点。您的代码应该尽可能短(但不能短),基于这些理由,原始代码要比您建议的更改好得多,并且还避免了将编译器弄糊涂而生成更糟糕代码的风险

“就引用而言,我不认为有任何潜在的性能下降,但如果我错了,请告诉我”一些(许多?)实现只存储堆栈基指针(EBP)如果您通过引用捕获。访问捕获的变量不会再慢。
T::iterator
必须是
typename T::iterator
btw。但是我宁愿使用
auto const it=…;
有趣的是,为什么必须有typename?有关详细解释,请参阅。编译器知道
T
是一种类型,b但是它不知道在解析模板时,
t::iterator
是一种类型。这些数字不会是非常随机的。使用,嗯,任何适合的方法。此外,我只会使用一个自排序容器,或者显式的最后排序步骤。是的,但这是编译器可以优化的吗?如果复制构造函数是内联的没有副作用,可以优化。嗯。我不确定我是否理解。第一个示例仍然隐式调用复制构造函数,对吗?内联似乎不会使这些等效。我缺少什么吗?编译器可能会检测到构造函数没有副作用,看到变量只是一个临时变量,然后优化我可能完全不喜欢,但我原以为RVO会允许删除拷贝,不管副作用如何?