简体   繁体   中英

Performance of golang style defer scope guard in C++

After reading this question on implementing Go's defer in C++:

golang-style "defer" in C++

I had a question on the performance of the go-defer like guard clause in given in one of the answers. It uses a shared_ptr deleter which ignores the passed object address.

If the deleter ignores the address using an unnamed parameter, will it still be passed on the stack.

Will there be any difference in any of the following ways of accomplishing the defer?

#include <memory>
#include <iostream>
#include <functional>

using namespace std;
using defer = shared_ptr<void>;

int main() {
    defer defer0 (nullptr, [](...) { cout << "defer0\n"; }); // this is the version i've seen

    // but will the performance be any different using any of these?
    shared_ptr<int> defer1(nullptr, [](int* dummy) { cout << "defer1\n"; });
    shared_ptr<int> defer2(nullptr, [](int*) { cout << "defer2\n"; });
    shared_ptr<void> defer3(nullptr, [](void*) { cout << "defer3\n"; });

    unique_ptr<int,void(*)(int*)> defer4(nullptr, [](int*) { cout << "defer4\n"; });

    cout << "Hello\n";
}

You can check out what is built for each of the implementations here: godbolt .

In short, there's no difference between versions 0-3, the pointer gets passed to the deleter function the same way in each case.

If you're looking for performance though, using a std::shared_ptr for this purpose is not a good idea. Shared pointers need to allocate memory for resource counting, which is totally unnecessary for a finalizer.

The std::unique_ptr case (with a dummy variable so the deleter is actually called) will work with the least overhead. However, a more dedicated class would be more sensible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM