【发布时间】:2016-07-04 16:43:57
【问题描述】:
我有一个分析 150,000 个文件的程序。 Valgrind 报告没有内存泄漏,但程序会随着时间的推移而变慢。
一些问题与过于频繁地使用 std::string 和 mktime 花费太多时间有关。 (见C++ slows over time reading 70,000 files)
但随着时间的推移,它仍然会变慢。 Lotharyx 建议容器使用导致堆碎片。
我阅读了关于不同 STL 容器优缺点的各种流程图,但我不太明白。
在下面的伪代码中,我不确定我是否做出了正确的选择来避免堆碎片。
fileList.clear()
scan all disks and build "fileList", a std::set of file paths matching a pattern.
// filepaths are named by date, eg 20160530.051000, so are intrinsically ordered
foreach(filePath in fileList)
{
if (alreadyHaveFileDetails(filePath))
continue;
// otherwise
collect file details into a fileInfoStruct; // like size, contents, mod
fileInfoMap[time_t date] = fileInfoStruct;
}
// fileInfoMap is ordered collection of information structs of about 100,000 files
// traverse the list in order
foreach (fileInfo in fileInfoMap)
{
if (meetsCondition(fileInfo))
{
TEventInfo event = makeEventInfo()
eventList.push_back(event);
}
}
并且上述序列永远重复。
所以对于容器的选择,我使用过(或需要):
fileList -- 包含 150,000 个路径名的唯一字符串列表。
我选择 std::set 是因为它会自动处理重复项并自动维护排序顺序。
没有随机访问,只添加条目,对它们进行排序(手动或自动),然后迭代它们。
fileInfoMap -- 由与文件日期相对应的 time_t 时间戳键入的结构数组。
我选择了std::map。它也将有 150,000 个条目,因此会占用大量内存。
没有随机访问,只将条目添加到一端。必须遍历它们,并在必要时从中间删除条目。
eventList——“事件”结构的小列表,比如 50 个项目。
我选择了 std::vector。不知道为什么真的。
没有随机访问,只在一端添加条目,然后遍历集合。
我对 C++ 还很陌生。感谢您的考虑。
【问题讨论】:
-
我不相信你的烦恼是由碎片引起的……
-
如果不是碎片那又怎样?
-
这是在调试版本的 Windows 上吗?
-
@Danny 我给你留下了关于你上一个问题的答案。
-
Centos 6 与 3.10 内核。用 -g 编译
标签: c++ stdvector heap-fragmentation