On Wed, Aug 16, 2017 at 12:09 PM, Daniel Langr <daniel.la...@gmail.com> wrote: > When compiling the following code: > > int* ptr = nullptr; > delete ptr; > > GCC 7.1 on x86_64 generates a delete-operator-related call instruction in > the resulting program with both -O2 and -O3 optimization flags. This is a > nonsense piece of code, indeed, but imagine a class that has an owning raw > pointer (please, don't tell me to use unique_ptr, there are such classes in > the real world). Then, this class needs to call delete in its move > assignment operator and destructor: > > class X { > T* ptr_; > public: > X() ptr_(nullptr) { } > X& operator=(X&& rhs) { > delete ptr_; > ptr_ = rhs.ptr_; > rhs.ptr_ = nullptr; > return *this; > } > ~X() { delete ptr_; } > ... > }; > Invoking std::swap with objects of class X then yields deletion of null > pointer 3 times (2 times within move assignment operator and once within > destructor). Since GCC doesn't optimize out these null-pointer deletions and > generate corresponding call instructions, whole swapping has some > performance penalty. > > I found out that if I change 'delete ptr_;' to 'if (ptr_) delete ptr_;', > then no call instructions are generated. So, I did a benchmark that sorted > 100M randomly-shuffled objects of class X (where T was int) with std::sort. > Here are measured sorting times: > > 1) 40.8 seconds with plain 'delete ptr_;', > 2) 31.5 seconds with 'if (ptr_) delete ptr_;', > 3) 31.3 seconds with additional custom swap free function for class X. > > This is quite a big performance difference between first two cases. Wouldn't > be nice if g++ was able to optimize out deletion of null pointers? I guess > in cases such as above mentioned one the null pointers can be recognized by > static analysis. (As far as I know omitting delete operator calls is > standard-compliant. Both Clang and Intel compilers did this in my tests.)
I suppose one needs to mark operator delete specially, like we do for new with DECL_IS_OPERATOR_NEW. Then the middle-end can delete those calls (the flag would mean there's no side-effect in case you pass NULL). Richard. > Cheers, > Daniel