Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.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++ 对for构造中的第二个表达式使用size()是否总是错误的?_C++ - Fatal编程技术网

C++ 对for构造中的第二个表达式使用size()是否总是错误的?

C++ 对for构造中的第二个表达式使用size()是否总是错误的?,c++,C++,在下面的示例中,我是否应该期望在循环中每次都调用values.size()?在这种情况下,引入一个临时的vectorSize变量可能是有意义的。或者,现代编译器应该能够通过识别向量大小不能改变来优化调用 double sumVector(const std::vector<double>& values) { double sum = 0.0; for (size_t ii = 0; ii < values.size(); ++ii) {

在下面的示例中,我是否应该期望在循环中每次都调用
values.size()
?在这种情况下,引入一个临时的
vectorSize
变量可能是有意义的。或者,现代编译器应该能够通过识别向量大小不能改变来优化调用

double sumVector(const std::vector<double>& values) {
    double sum = 0.0;
    for (size_t ii = 0; ii < values.size(); ++ii) {
        sum += values.at(ii);
    }
}
double-sumVector(常量标准::向量和值){
双和=0.0;
对于(size_t ii=0;ii

请注意,我不关心是否有更有效的方法对向量的内容求和,这个问题只是关于在for构造中使用size()。

这一切都取决于向量的size实现是什么,编译器的攻击性有多大,以及它是否侦听/使用内联指令

我会更具防御性,并引入临时代码,因为您无法保证编译器的效率

当然,如果这个例程被调用一次或两次,并且向量很小,这真的不重要

如果它会被调用数千次,那么我会使用临时的

有些人可能会说这是过早的优化,但我倾向于不同意这种评估。
当您试图优化代码时,您并不是在以性能为名而投入时间或混淆代码


我很难将重构理解为优化。但最后,这是按照“你说西红柿,我说西红柿”的思路进行的。

我同意贝诺特的观点。引入一个新变量,特别是int甚至short,会比每次调用它有更大的好处


如果循环变得足够大,可能会影响性能,那么就不必担心了。

编译器应该内联std::vector中的size方法,这意味着对size()的每次调用都会被其实际主体所取代(有关内联的更多信息,请参阅问题)。因为在大多数实现中,size()基本上计算end()和begin()之间的差异(也应该是内联的),所以您不必太担心性能的损失

此外,如果我没记错的话,有些编译器非常“聪明”,能够在for构造的第二部分检测表达式的常量,并生成只对表达式求值一次的代码。

从“for”构造中的size()开始,直到需要优化速度为止

for (size_t ii = 0, count = values.size();  ii < count;  ++ii)

如果速度太慢,请寻找加快速度的方法,例如使用临时变量保存大小的结果。

如果在临时变量中保存向量的大小,则与编译器无关


我的猜测是,大多数编译器都会以某种方式优化代码,即size()只被调用一次。但是使用临时变量可以保证,size()只会被调用一次

值得注意的是,即使你要处理数以百万计的项目,开销也可以忽略不计

在任何情况下,都应该使用迭代器编写,因为访问特定示例可能会有更多开销

编译器真的不可能假设size()不会改变,因为它可以

如果迭代的顺序不重要,那么您可以始终按照稍微更有效的方式编写它

for (int i=v.size()-1; i>=0 ;i--)
{
   ...
}

编译器不知道.size()的值在调用之间是否发生变化,因此不会进行任何优化。我知道您刚刚询问了.size()的使用,但是您应该使用迭代器

std::vector<double>::const_iterator iter = values.begin();
for(; iter != values.end(); ++iter)
{
    // use the iterator here to access the value.
}
std::vector::const_迭代器iter=values.begin();
对于(;iter!=values.end();++iter)
{
//使用此处的迭代器访问该值。
}

在本例中,对.end()的调用类似于使用.size()暴露的问题。如果您知道循环不会在向量中执行任何使迭代器无效的操作,则可以在进入循环之前将迭代器初始化到.end()位置,并将其用作边界。

在这种情况下,使用迭代器更干净-在某些情况下甚至更快。只有一个对容器的调用——如果还有向量成员,则获取持有指向向量成员指针的迭代器,否则为null


当然
可以变成
,而
完全不需要临时变量-您甚至可以向sumVector函数传递迭代器,而不是常量引用/值。

始终按照您的意思第一次编写代码。如果要在向量上从零迭代到size(),请这样编写。不要将对size()的调用优化为临时变量,除非您已将调用分析为程序中需要优化的瓶颈


很有可能,一个好的编译器将能够优化对size()的调用,特别是在向量声明为常量的情况下。

这里有一种方法使其显式-size()只调用一次

for (size_t ii = 0, count = values.size();  ii < count;  ++ii)
for(size_t ii=0,count=values.size();ii
编辑:我被要求实际回答这个问题,所以这是我最好的答案

编译器通常不会优化函数调用,因为它不知道从一个调用到下一个调用是否会得到不同的返回值。如果循环中存在无法预测其副作用的操作,它也不会进行优化。内联函数可能会有所不同,但没有什么是可以保证的。编译器更容易优化局部变量

有些人会称之为过早的优化,我同意很少有情况下你会注意到速度的差异。但是,如果它不能使代码更难理解,为什么不把它看作是最佳实践呢?当然不会痛的

另外,在我仔细阅读答案之前,我写了这篇文章,我相信我们完全一致。

size_t size = values.size();
for (size_t ii = 0; ii < size; ++ii) {
    sum += values.at(ii)
}
for (size_t ii = 0; ii < values.size(); ++ii) {
    sum += values.at(ii);
}
double sum = std::accumulate(values.begin(), values.end(), 0);