Why are new()/delete() slower than malloc()/free()?

Why new()/delete() is slower than malloc()/free()?

EDIT:

Thanks for the answers so far. Please kindly point out specifications of standard C++ implementation of new() and delete() if you have them thanks!

Answers


Look at this piece of C code:

struct data* pd = malloc(sizeof(struct data));
init_data(pd);

The new operator in C++ is essentially doing what the above piece of code does. That's why it is slower than malloc().

Likewise with delete. It's doing the equivalent of this:

deinit_data(pd);
free(pd);

If the constructors and destructors are empty (like for built-ins), new and delete shouldn't be slower than malloc() and free() are. (If they are, it's often due to the fact that common implementations call malloc()/free() under the hood, so they are a wrapper around them. Wrapping costs. Also, there might be code that needs to find out that no constructors/destructors are to be called. That would cost, too.)

Edit To answer your additional question:

new and delete aren't functions, they are operators. This: new data() is called a new expression. It does two things. First it calls the operator new, then it initializes the object, usually by invoking the appropriate constructor. (I say "usually" because built-ins don't have constructors. But a new expression involving a built-in works the same nevertheless.)

You can manipulate both of these phases. You can create your own constructors to manipulate initialization of your types and you can overload operator new (even with several overloads having different additional arguments and also specifically for each class, if you want) in order to manipulate allocation of free storage. If you don't implement your own operator new, the version from the standard library is used. A common implementation of this calls malloc().

Likewise, if you write delete pd, called a delete expression, two things happen: depending on pd, the object is de-initialized, usually by calling its destructor, then the memory is released by calling the appropriate operator delete.

Again, you can manipulate both phase, by writing your own destructor, and by writing your own version of operator delete. (The version of operator delete that comes with your standard library is often implemented to call free().)


new and delete are dealing with construction/destruction for which part of their work is the effectively calling malloc() and free() - malloc() and free() are raw memory allocation/deallocation.


If you use them to allocate "plain old data", such that the constructor/destructor are trivial, they are unlikely to differ at all significantly in speed from malloc/free. It's possible (likely?) that you made a mistake somewhere in your measurements that biased the results. Really all they do aside from calling on to malloc/free is execute type's constructor/destructor (multiple times for arrays).


When the new operator is called, two things happen:

  1. Memory is allocated for the object on the heap.
  2. The constructor of the object is invoked.

So, due to the overhead of construction of objects, new is slower that malloc.

Similarly, delete does following two things:

  1. Calls destructor of the heap object.
  2. Deallocates the object's memory.

In short, malloc allocates only raw memory, whereas new not only allocates raw memory but also turns raw memory into objects.


They should not be, and they aren't in the code base I am working in.

Where I work, malloc/free is slower and more inefficient than new/delete for two reasons:

  • free() does not know the size of the object, whereas delete often has this size at compile-time.
  • malloc() does not know the type of the object it is allocating, so it has to always provide memory with 16-byte alignment. This can often be wasteful.

Need Your Help

Error 'tunneling socket' while executing npm install

npm protractor

I'm getting the error shown below while trying to execute 'npm install' command.