为什么泄漏内存比在动态数组上执行 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[] 比泄漏内存表现出更好的性能?或者我在这里缺少什么

有很多种可能性。

  1. 测试存在缺陷,时间与您的想法不符。
  2. 释放内存后,运行时可以每次为您分配相同的块。但是当不释放内存时,运行时必须分配一个新块,这可能需要时间并且可能必须从 OS 分配更多内存(取决于内存分配在您的特定环境中的工作方式)。
  3. 还有很多。

delete[] 函数做的很少,但会非常快。系统可能会在每次迭代中继续返回相同的内存,并且都可以在 userspace 中完成(what happens in the kernel during malloc? 有更多详细信息)。

内存以块的形式分配给您的进程。如果你让内存泄漏,你将在某些时候需要使用内核调用来扩展内存 space。这些内核调用可能比删除调用昂贵得多。