g ++比使用列表的visual studio慢1000倍?

时间:2013-12-19 23:40:44

标签: c++ visual-studio optimization stl g++

请考虑以下代码段:

#include <iostream>
#include <ctime>
#include <vector>
#include <list>
using namespace std;

#define NUM_ITER 100000

int main() {
    clock_t t = clock();
    std::list< int > my_list;
    std::vector< std::list< int >::iterator > list_ptr;

    list_ptr.reserve(NUM_ITER);

    for(int i = 0; i < NUM_ITER; ++i) {
        my_list.push_back(0);
        list_ptr.push_back(--(my_list.end()));
    }

    while(my_list.size() > 0) {
        my_list.erase(list_ptr[list_ptr.size()-1]);
        list_ptr.pop_back();
    }

    cout << "Done in: " << 1000*(clock()-t)/CLOCKS_PER_SEC << " msec!" << endl;
}

当我使用visual studio编译并运行它时,启用了所有优化,我得到了输出:

  

完成:8毫秒!

当我用g ++编译并运行它时,使用标志

  

g ++ main.cpp -pedantic -O2

我得到了输出

  

完成:7349毫秒!

这是鲁莽慢1000倍。这是为什么?根据“cppreference”调用列表中的擦除应该只使用恒定时间。

代码在同一台机器上编译和执行。

2 个答案:

答案 0 :(得分:10)

可能是GCC发布的实现并未存储大小,而MSVC发布的实现也是如此。在这种情况下,内环为O(n ^ 2),GCC,O(n)为MSVC。

无论如何,C ++ 11要求list :: size是常量时间,你可能想把它报告为bug。

答案 1 :(得分:3)

更新解决方法:

您可以避免多次致电size()

size_t my_list_size = my_list.size();
while(my_list_size > 0) {
    accum += *list_ptr[list_ptr.size()-1];
    my_list.erase(list_ptr[list_ptr.size()-1]);
    --my_list_size;
    list_ptr.pop_back();
}

现在报告10毫秒。

修改 他们的列表实现效率不高。我尝试用以下代替:

#include <iostream>
#include <ctime>
#include <boost/container/vector.hpp>
#include <boost/container/list.hpp>
using namespace std;

#define NUM_ITER 100000

int main() {
    clock_t t = clock();
    boost::container::list< int > my_list;
    boost::container::vector< boost::container::list< int >::iterator > list_ptr;

    list_ptr.reserve(NUM_ITER);

    for(int i = 0; i < NUM_ITER; ++i) {
        my_list.push_back(rand());
        list_ptr.push_back(--(my_list.end()));
    }

    unsigned long long volatile accum = 0;

    while(my_list.size() > 0) {
        accum += *list_ptr[list_ptr.size()-1];
        my_list.erase(list_ptr[list_ptr.size()-1]);
        list_ptr.pop_back();
    }

    cout << "Done in: " << 1000*(clock()-t)/CLOCKS_PER_SEC << " msec!" << endl;
    cout << "Accumulated: " << accum << "\n";
}

现在在我的机器上运行〜0ms,而在同一台机器上使用std :: list运行~7s。

sehe@desktop:/tmp$ ./test
Done in: 0 msec!
Accumulated: 107345864261546