在下面的代码中,我实现并填充了一个unordered_map
(函数unuseful()
),然后我使用malloc
来分配内存。malloc 调用经过的时间非常长(存储 1001 字节或多或少需要 135 毫秒):为什么?
我正在使用在 Lubuntu 13.10 上运行的 gcc4.8.1 进行编译。编译命令是g++ -std=c++11 main.cpp
(如果我添加优化,如-O1
,-O2
,-O3
,-Ofast
或-Wno-write-strings
,结果不会改变)。我正在测试一个(更复杂的)程序的效率,我真的需要了解哪些部分需要多少时间。
如果我删除函数unuseful()
或将代码从函数unuseful()
移动到主函数,则时间变为 0。如果我分配 1000 字节而不是 1001,则时间变为 0。如果我使用 for 循环重复两次实验,第一个实验的时间再次为 135 毫秒,第二个实验的时间为 0。
代码如下。
#include <iostream>
#include <unordered_map>
#include <sys/time.h>
#include <unistd.h>
using namespace std;
void unuseful() {
unordered_map <string, int> nodes;
for (int nn = 0; nn < 1000000; nn++) {
nodes[to_string(nn)] = nn;
}
}
long getTimeMilliseconds() {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_usec / 1000 + tv.tv_sec * 1000;
}
int main() {
unuseful();
long start = getTimeMilliseconds();
int *dist = (int*) malloc(1001);
cout << "Time: " << getTimeMilliseconds() - start << "n";
cout << "Something unuseful to avoid compiler optimizations: " << dist[1000] << "n";
}
我最好的猜测是堆变得过于复杂,并且在释放节点时 unuseful() 方法的退出处,堆是碎片化的,它们的第一个 malloc 会引发堆同步。出于某种原因,我不明白 malloc 它 1000 堆是否没有清理......如果您保留节点映射,它的行为方式是否相同?
另一个想法:如果你删除无用的()调用怎么办?编译器不会初始化'start并在无用()之前调用getTimeMilliseconds吗?