为什么泄漏内存比在动态数组上执行 delete[] 慢
Why leaking memory is slower than doing delete[] on the dynamic array
我刚开始使用 google 基准进行微基准测试,我得到了我无法真正解释的结果。我有一个函数 URLify(编码空格的基本函数)。我将我的字符串转换为 char * 并将其传递给函数
这就是我使用 google 基准测试和全面优化对其进行测试的方式。使用 VS 2015 x64
while (state.KeepRunning()) {
char* ch = new char[str.length()*2 ]; //str is a string I want to encode
memcpy(ch, &str[0], str.length() + 1);
URLify(ch, str.length());
delete[] ch;
}
这是进行 30000 次迭代和 5 次重复的结果
BenchURLify/iterations:30000/repeats:5 5370 ns 5729 ns 30000
BenchURLify/iterations:30000/repeats:5 5366 ns 5208 ns 30000
BenchURLify/iterations:30000/repeats:5 5349 ns 5208 ns 30000
BenchURLify/iterations:30000/repeats:5 5364 ns 5729 ns 30000
BenchURLify/iterations:30000/repeats:5 5356 ns 5208 ns 30000
BenchURLify/iterations:30000/repeats:5_mean 5361 ns 5417 ns 5
BenchURLify/iterations:30000/repeats:5_median 5364 ns 5208 ns 5
BenchURLify/iterations:30000/repeats:5_stddev 8.48 ns 285 ns 5
但是当我从代码中删除 delete[] 时 google 基准显示了不同的结果,而不是我预期的结果。我认为每次迭代都释放内存比泄漏内存要慢。但这是没有 delete[] ch
的结果
BenchURLify/iterations:30000/repeats:5 7240 ns 7292 ns 30000
BenchURLify/iterations:30000/repeats:5 7245 ns 7292 ns 30000
BenchURLify/iterations:30000/repeats:5 7116 ns 7292 ns 30000
BenchURLify/iterations:30000/repeats:5 7091 ns 7292 ns 30000
BenchURLify/iterations:30000/repeats:5 7116 ns 6771 ns 30000
BenchURLify/iterations:30000/repeats:5_mean 7162 ns 7188 ns 5
BenchURLify/iterations:30000/repeats:5_median 7116 ns 7292 ns 5
BenchURLify/iterations:30000/repeats:5_stddev 74.6 ns 233 ns 5
所以我的问题是为什么 delete[] 比泄漏内存表现出更好的性能?或者我在这里缺少什么
有很多种可能性。
- 测试存在缺陷,时间与您的想法不符。
- 释放内存后,运行时可以每次为您分配相同的块。但是当不释放内存时,运行时必须分配一个新块,这可能需要时间并且可能必须从 OS 分配更多内存(取决于内存分配在您的特定环境中的工作方式)。
- 还有很多。
delete[] 函数做的很少,但会非常快。系统可能会在每次迭代中继续返回相同的内存,并且都可以在 userspace 中完成(what happens in the kernel during malloc? 有更多详细信息)。
内存以块的形式分配给您的进程。如果你让内存泄漏,你将在某些时候需要使用内核调用来扩展内存 space。这些内核调用可能比删除调用昂贵得多。
我刚开始使用 google 基准进行微基准测试,我得到了我无法真正解释的结果。我有一个函数 URLify(编码空格的基本函数)。我将我的字符串转换为 char * 并将其传递给函数
这就是我使用 google 基准测试和全面优化对其进行测试的方式。使用 VS 2015 x64
while (state.KeepRunning()) {
char* ch = new char[str.length()*2 ]; //str is a string I want to encode
memcpy(ch, &str[0], str.length() + 1);
URLify(ch, str.length());
delete[] ch;
}
这是进行 30000 次迭代和 5 次重复的结果
BenchURLify/iterations:30000/repeats:5 5370 ns 5729 ns 30000
BenchURLify/iterations:30000/repeats:5 5366 ns 5208 ns 30000
BenchURLify/iterations:30000/repeats:5 5349 ns 5208 ns 30000
BenchURLify/iterations:30000/repeats:5 5364 ns 5729 ns 30000
BenchURLify/iterations:30000/repeats:5 5356 ns 5208 ns 30000
BenchURLify/iterations:30000/repeats:5_mean 5361 ns 5417 ns 5
BenchURLify/iterations:30000/repeats:5_median 5364 ns 5208 ns 5
BenchURLify/iterations:30000/repeats:5_stddev 8.48 ns 285 ns 5
但是当我从代码中删除 delete[] 时 google 基准显示了不同的结果,而不是我预期的结果。我认为每次迭代都释放内存比泄漏内存要慢。但这是没有 delete[] ch
的结果BenchURLify/iterations:30000/repeats:5 7240 ns 7292 ns 30000
BenchURLify/iterations:30000/repeats:5 7245 ns 7292 ns 30000
BenchURLify/iterations:30000/repeats:5 7116 ns 7292 ns 30000
BenchURLify/iterations:30000/repeats:5 7091 ns 7292 ns 30000
BenchURLify/iterations:30000/repeats:5 7116 ns 6771 ns 30000
BenchURLify/iterations:30000/repeats:5_mean 7162 ns 7188 ns 5
BenchURLify/iterations:30000/repeats:5_median 7116 ns 7292 ns 5
BenchURLify/iterations:30000/repeats:5_stddev 74.6 ns 233 ns 5
所以我的问题是为什么 delete[] 比泄漏内存表现出更好的性能?或者我在这里缺少什么
有很多种可能性。
- 测试存在缺陷,时间与您的想法不符。
- 释放内存后,运行时可以每次为您分配相同的块。但是当不释放内存时,运行时必须分配一个新块,这可能需要时间并且可能必须从 OS 分配更多内存(取决于内存分配在您的特定环境中的工作方式)。
- 还有很多。
delete[] 函数做的很少,但会非常快。系统可能会在每次迭代中继续返回相同的内存,并且都可以在 userspace 中完成(what happens in the kernel during malloc? 有更多详细信息)。
内存以块的形式分配给您的进程。如果你让内存泄漏,你将在某些时候需要使用内核调用来扩展内存 space。这些内核调用可能比删除调用昂贵得多。