C++:删除与免费和性能

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/328834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:40:42  来源:igfitidea点击:

C++: delete vs. free and performance

c++pointersperformance

提问by user41522

  1. Consider:

    char *p=NULL;
    free(p) // or
    delete p;
    

    What will happen if I use freeand deleteon p?

  2. If a program takes a long time to execute, say 10 minutes, is there any way to reduce its running time to 5 minutes?

  1. 考虑:

    char *p=NULL;
    free(p) // or
    delete p;
    

    如果我使用会发生什么freedeletep

  2. 如果一个程序需要很长时间才能执行,比如说 10 分钟,有没有办法将它的运行时间减少到 5 分钟?

回答by strager

Some performance notes about new/delete and malloc/free:

关于 new/delete 和 malloc/free 的一些性能说明:

malloc and free do notcall the constructor and deconstructor, respectively. This means your classes won't get initalized or deinitialized automatically, which could be bad (e.g. uninitalized pointers)! This doesn't matter for POD data types like char and double, though, since they don't really have a ctor.

malloc 和 free分别调用构造函数和析构函数。这意味着您的类不会自动初始化或取消初始化,这可能很糟糕(例如未初始化的指针)!不过,这对于像 char 和 double 这样的 POD 数据类型并不重要,因为它们并没有真正的ctor。

new and delete docall the constructor and deconstructor. This means your class instances are initalized and deinitialized automatically. However, normally there's a performance hit (compared to plain allocation), but that's for the better.

new和delete调用构造函数和析构。这意味着您的类实例会自动初始化和取消初始化。然而,通常会有性能下降(与普通分配相比),但这是更好的。

I suggest staying consistent with new/malloc usage unless you have a reason (e.g. realloc). This way, you have less dependencies, reducing your code size and load time (only by a smidgin, though). Also, you won't mess up by free'ing something allocated with new, or deleting something allocated with malloc. (This will most likely cause a crash!)

除非您有原因(例如 realloc),否则我建议与 new/malloc 用法保持一致。这样,您的依赖项更少,减少了代码大小和加载时间(尽管只有 smidgin)。此外,您不会因为释放用 new 分配的东西或删除用 malloc 分配的东西而搞砸。(这很可能会导致崩溃!)

回答by activout.se

Answer 1: Both free(p)and delete pwork fine with a NULL pointer.

答1:无论free(p)delete p做工精细用NULL指针。

Answer 2: Impossible to answer without seeing the slow parts of the code. You should profile the code! If you are using Linux I suggest using Callgrind (part of Valgrind) to find out what parts of the execution takes the most time.

答案 2:无法在没有看到代码缓慢部分的情况下回答。你应该分析代码!如果您使用的是 Linux,我建议您使用 Callgrind(Valgrind 的一部分)来找出执行过程中花费最多时间的部分。

回答by cic

Question one: nothing will happen.

问题一:什么都不会发生。

From the current draft of ISO/IEC 14882 (or: C++):

来自 ISO/IEC 14882(或:C++)的当前草案:

20.8.15 C Library [c.malloc]

The contents [of <cstdlib>, that is: where freelives,] are the same as the Standard C library [(see intro.refs for that)] header <stdlib.h>, with the following changes: [nothing that effects this answer].

20.8.15 C 库 [c.malloc]

内容 [of <cstdlib>, 即: where freeliving,] 与标准 C 库 [(请参阅 intro.refs 了解)] header 相同<stdlib.h>,但有以下更改:[没有影响此答案的内容]。

So, from ISO/IEC 9899:1999 (or: C):

因此,从 ISO/IEC 9899:1999(或:C):

7.20.3.2 The freefunction

If [the] ptr[parameter] is a null pointer, no action occurs.

7.20.3.2free功能

如果 [the] ptr[parameter] 是空指针,则不会发生任何操作

From the C++ standard again, for information about deletethis time:

再次来自 C++ 标准,有关delete这次的信息:

3.7.4.2 Deallocation functions [basic.stc.dynamic.deallocation]

The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect.

3.7.4.2 释放函数[basic.stc.dynamic.deallocation]

提供给释放函数的第一个参数的值可能是空指针值;如果是这样,并且如果释放函数是标准库中提供的函数,则调用无效

See also:

也可以看看:

回答by Steve Jessop

Nothing will happen if you call free with a NULL parameter, or delete with an NULL operand. Both are defined to accept NULL and perform no action.

如果您使用 NULL 参数调用 free 或使用 NULL 操作数删除,则不会发生任何事情。两者都被定义为接受 NULL 并且不执行任何操作。

There are any number of thing you can change in C++ code which can affect how fast it runs. Often the most useful (in approximate order) are:

您可以在 C++ 代码中更改许多会影响其运行速度的内容。通常最有用的(大致顺序)是:

  • Use good algorithms. This is a big topic, but for example, I recently halved the running time of a bit of code by using a std::vector instead of a std::list, in a case where elements were being added and removed only at the end.
  • Avoid repeating long calculations.
  • Avoid creating and copying objects unnecessarily (but anything which happens less than 10 million times per minute won't make any significant difference, unless you're handling something really big, like a vector of 10 million items).
  • Compile with optimisation.
  • Mark commonly-used functions (again, anything called more than 100 million times in your 10 minute runtime), as inline.
  • 使用好的算法。这是一个很大的话题,但例如,我最近使用 std::vector 而不是 std::list 将一些代码的运行时间减半,以防元素仅在最后添加和删除.
  • 避免重复长时间的计算。
  • 避免不必要地创建和复制对象(但是每分钟发生少于 1000 万次的任何事情都不会产生任何显着差异,除非您正在处理非常大的东西,例如 1000 万个项目的向量)。
  • 编译优化。
  • 将常用函数(同样,在 10 分钟运行时间中调用超过 1 亿次的任何函数)标记为内联。

Having said that, divideandconquer is absolutely right - you can't effectively speed your program up unless you know what it spends its time doing. Sometimes this can be guessed correctly when you know how the code works, other times it's very surprising. So it's best to profile. Even if you can't profile the code to see exactly where the time is spent, if you measure what effect your changes have you can often figure it out eventually.

话虽如此,分而治之是绝对正确的——除非你知道它花时间做什么,否则你不能有效地加速你的程序。有时,当您知道代码的工作原理时,就可以正确猜出这一点,有时则非常令人惊讶。所以最好进行简介。即使您无法分析代码以准确查看时间花费在何处,但如果您衡量更改的效果,您通常最终可以弄清楚。

回答by E Dominique

On question 2:
Previous answers are excellent. But I just wanted to add something about pre-optimization. Assuming a program of moderate complexity, the 90/10 rule usually applies - i.e. 90% of the execution time is spent in 10% of the code. "Optimized" code is often harder to read and to maintain. So, always solve the problems first, then see where the bottlenecks are (profiling is a good tool).

关于问题 2:
以前的答案非常好。但我只是想添加一些关于预优化的内容。假设一个中等复杂度的程序,90/10 规则通常适用——即 90% 的执行时间花在 10% 的代码上。“优化”代码通常更难阅读和维护。所以,总是先解决问题,然后看看瓶颈在哪里(分析是一个很好的工具)。

回答by Naveen

As others have pointed out deleting (or freeing) a NULL pointer will not do anything. However if you had allocated some memory then whether to use free() or delete depends upon the method you used to allocate them. For example, if you had used malloc() to allocate memory then you should free() and if you had used new to allocate then you should use delete. However, be careful not to mix the memory allocations. Use a single way to allocate and deallocate them.

正如其他人指出的那样,删除(或释放)空指针不会做任何事情。但是,如果您分配了一些内存,那么是使用 free() 还是 delete 取决于您用于分配它们的方法。例如,如果您使用 malloc() 分配内存,则应使用 free();如果使用 new 分配内存,则应使用 delete。但是,请注意不要混合内存分配。使用单一方式分配和解除分配它们。

For the second question, it will be very difficult to generalize without seeing the actual code. It should be taken on a case by case basis.

对于第二个问题,不看实际代码很难概括。应根据具体情况进行处理。

回答by Mike Dunlavey

Good answers all.

都好回答。

On the performance issue, thisprovides a method that most can't imagine will work, but a few know it does, surprisingly well.

在性能问题上,提供了一种大多数人无法想象会奏效的方法,但少数人知道它确实有效,而且效果出奇地好。

The 90/10 rule is true. In my experience, there usually are multiple trouble spots, and they usually are at mid-levels of the call stack. They often are caused by using over-general data structures, but you should never fix something unless you've proven that it actually is a problem. Performance problems are amazingly unpredictable.

90/10 规则是正确的。根据我的经验,通常有多个故障点,它们通常位于调用堆栈的中间级别。它们通常是由使用过于通用的数据结构引起的,但是除非您已经证明它确实是一个问题,否则您永远不应该修复某些东西。性能问题出奇地不可预测。

Fixing any single performance problem may not give you the speedup you need, but each one you fix makes the remaining ones take a larger percentage of the remaining time, so they become easier to find. The speedups combine in a compounded fashion, so you may be surprised at the final result.

修复任何单个性能问题可能不会给您带来所需的加速,但是您修复的每个问题都会使剩余的问题占用更大比例的剩余时间,因此它们变得更容易找到。加速以复合方式结合,因此您可能会对最终结果感到惊讶。

When you can no longer find significant problems that you can fix, you've done about as well as you can. Sometimes, at that point, a redesign (such as using code generation) can set off a further round of speedups.

当您无法再找到可以修复的重大问题时,您已经尽力了。有时,在那个时候,重新设计(例如使用代码生成)可以引发进一步的加速。