c++ - 为什么我插入 STL 列表运行缓慢?

标签 c++ list stl

我正在尝试使用邻接表实现无向图。我使用了以下代码:

int v,e;
scanf("%d%d",&v,&e);
list<int> graph[3000];
for(int i=0;i<e;i++){
    int a,b;
    scanf("%d%d",&a,&b);
    graph[a].push_back(b);
    graph[b].push_back(a);
}

为了测试我的代码的运行时间,我创建了一个包含 3000 个顶点和所有可能边的输入文件。运行需要 2.2 秒。我尝试通过将其更改为二维数组来进行优化,如下所示

int graph[3000][3000];

for(int i=0;i<e;i++){
    int a,b;
    scanf("%d%d",&a,&b);
    graph[a][p[a]]=b;
    graph[b][p[b]]=a;
    p[a]++;
    p[b]++;
}

其中“p”的大小为 3000,初始化为全零。对于相同的输入文件,此代码仅需 0.35 秒即可运行。我正在使用 gcc-4.3.2 编译器。我知道列表末尾的插入可以在恒定时间内完成,那么为什么第一个代码运行缓慢?是否有机会优化链表实现?

提前致谢

最佳答案

避免 std::list。这是一个双向链表,对缓存非常不友好(节点随机分布在内存中)并且涉及大量开销(每个元素 2 个指针)。因此,每次附加内容时,列表都会分配 2*sizeof(void*)+sizeof(int) 字节以及 operator new 的额外内存管理开销。

在算法的后期,当您迭代这些值时,您实际上是在整个内存中跳跃,这会更慢。

二维数组没有这个问题,但确实会浪费一些内存。

我通常将邻接表表示为 vector 的 vector 。

std::vector<std::vector<int> > graph;

请注意, vector 还可以 push_back O(1) 中的值(以及 std::deque,它可以追加甚至更快,但在遍历时更慢)。如果期望图是密集的,那么邻接矩阵可能是更好的选择。

关于c++ - 为什么我插入 STL 列表运行缓慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15855577/

相关文章:

c# - 如何通过读取用户输入将变量添加到我的列表中?

c++ - std::vector::erase()(多线程) 'Assertion ` px != 0' failed.'

使用接口(interface)的 C++ 命令行操作抽象

c++ - 可变参数宏 : how to solve "too many actual parameters for macro.."

c++ - 将 QByteArray 附加到 QDataStream?

c++ - 在 C++ 中加速图像过滤器

java - 循环遍历列表并根据数据创建 View

python - 如何在Python中将二进制元素的数据解析为列表列表?

c++ - 对 STL 容器的安全并行只读访问

c++ - `constexpr` 函数也应该是 `noexcept` 吗?