Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.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++11 - Fatal编程技术网

C++ 在可能的情况下,是否应避免循环的范围?

C++ 在可能的情况下,是否应避免循环的范围?,c++,c++11,C++,C++11,在我的DirectX程序中,我编写了一个循环,循环通过std::string,然后运行性能分析器,并意识到这个循环消耗了大量的cpu时间。更重要的是,当我运行我的程序时,我有大约1300 FPS。所以我决定用这个做点什么,我把基于范围的循环改为典型的迭代。我是说我改变了: for( char c : std_string_name ) 到 (大小i=0;i(从注释中移动) 基于范围的循环使用迭代器,由于额外的调试检查,VC++迭代器在调试模式下往往速度较慢;一旦在发布模式下,它们应该归结为指针

在我的DirectX程序中,我编写了一个循环,循环通过std::string,然后运行性能分析器,并意识到这个循环消耗了大量的cpu时间。更重要的是,当我运行我的程序时,我有大约1300 FPS。所以我决定用这个做点什么,我把基于范围的循环改为典型的迭代。我是说我改变了:

for( char c : std_string_name )

(大小i=0;i(从注释中移动)

基于范围的循环使用迭代器,由于额外的调试检查,VC++迭代器在调试模式下往往速度较慢;一旦在发布模式下,它们应该归结为指针,因此应该没有性能差异

此外,您的测试没有意义,因为:

  • 这样的空循环可能会被优化器优化掉,因此您只能在未优化的构建中可靠地运行测试——但在未优化的构建中,测试性能是没有意义的
  • 您只按特定顺序运行每个测试一次-这可能会给出误导性信息,例如,由于第一个循环中的缓存“预热”(尽管我不认为是这种情况,因为
    str
    刚刚被访问以进行构建);为了获得有统计意义的信息,你必须以随机顺序重复测试多次

我用你的代码写了以下内容:

#include <iostream>
#include <string>
#include <ctime>

int iter1( std::string str ){
    int sum = 0;
    for( char c : str ){
    sum += c;
    }
    return sum;
}

int iter2( std::string str ){
    int sum = 0;
    for( char &c : str ){
    sum += c;
    }
    return sum;
}

int iter3( std::string str ){
    int sum = 0;
    std::string::size_type len = str.length();
    for( size_t i=0;i<len;++i){
        char c = str[i];
    sum += c;
    }
    return sum;
}

int main(){

    std::string str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    for(int i=0;i<22;++i)
        str += str;

    clock_t a, b, c;
    clock_t aa, bb, cc;
    int sum = 0;

    a=clock();
    sum += iter1(str);
    aa = clock() -a ;

    b=clock();
    sum += iter2(str);
    bb=clock()-b;

    c=clock();
    sum += iter3(str);
    cc=clock()-c;

    std::cout << "aa=" << aa << " bb=" << bb << " cc=" << cc << " sum=" << sum << std::endl;
}
#包括
#包括
#包括
int iter1(std::string str){
整数和=0;
for(字符c:str){
总和+=c;
}
回报金额;
}
int iter2(std::string str){
整数和=0;
用于(字符和字符:str){
总和+=c;
}
回报金额;
}
int iter3(std::string str){
整数和=0;
std::string::size_type len=str.length();

对于(size_t i=0;i您是在调试模式还是发布模式下编译的?基于范围的循环使用迭代器,而VC++迭代器在调试模式下由于额外的调试检查往往速度较慢;一旦在发布模式下,它们应该归结为指针,因此性能应该没有差异。不要粘贴代码图像,在问题中编写代码您忘记了变量ant:
for(const char&c:std_string_name){…}
MSVS 2012必须有一个调试器。为什么不比较不同情况下的实际反汇编?
main
需要返回
int
。可能是基于范围的循环在检查std::string是否有更多元素时为每个迭代创建结束迭代器?此外,我在发布模式下测试了我的应用程序,现在我看不出有什么不同@MichalW:不,实际上,基于范围的循环的主要兴趣之一是它确保缓存
end
迭代器;尽管结果是修改循环中的迭代容器会导致未定义的行为。请注意,调试生成中的MSVC迭代器性能可以通过_迭代器_DEBU大大提高G_LEVEL#define。请看哇!谢谢!这个答案非常有用!当然应该注意,不同的编译器可能会有所不同,但并非所有基于范围的循环总是比基于迭代器的循环慢。还要注意,我确保循环做了一些事情(在本例中,计算校验和),就像空循环一样如果编译器足够聪明,“消失”。第三个变量速度最慢的原因是libstdc++的
std::string
是写时复制(这在C++11中是非法的,但他们保留它是为了ABI稳定性),因此它必须在每个可变访问上取消共享,就像非常量
操作符[]
在这里使用。当它们更改为一个正常的实现时,就像在MSVC中使用的一个类似的实现(使用SSO的非CoW),如果三者之间有任何有意义的区别,我会感到惊讶。
void main(){

    for(int i=0;i<10;++i)
        str += str;

    clock_t a, b, c;
    clock_t aa, bb, cc;

    a=clock();
    iter1(str);
    aa = clock() -a ;

    b=clock();
    iter2(str);
    bb=clock()-b;

    c=clock();
    iter3(str);
    cc=clock()-c;

}

void iter1( std::string str ){
    for( char c : str ){
    }
}

void iter2( std::string str ){
    for( char &c : str ){
    }
}

void iter3( std::string str ){
    for( size_t i=0;i<str.length();++i){
        char c = str[i];
    }
}
#include <iostream>
#include <string>
#include <ctime>

int iter1( std::string str ){
    int sum = 0;
    for( char c : str ){
    sum += c;
    }
    return sum;
}

int iter2( std::string str ){
    int sum = 0;
    for( char &c : str ){
    sum += c;
    }
    return sum;
}

int iter3( std::string str ){
    int sum = 0;
    std::string::size_type len = str.length();
    for( size_t i=0;i<len;++i){
        char c = str[i];
    sum += c;
    }
    return sum;
}

int main(){

    std::string str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    for(int i=0;i<22;++i)
        str += str;

    clock_t a, b, c;
    clock_t aa, bb, cc;
    int sum = 0;

    a=clock();
    sum += iter1(str);
    aa = clock() -a ;

    b=clock();
    sum += iter2(str);
    bb=clock()-b;

    c=clock();
    sum += iter3(str);
    cc=clock()-c;

    std::cout << "aa=" << aa << " bb=" << bb << " cc=" << cc << " sum=" << sum << std::endl;
}