unique_ptr 的开销有多大
unique_ptr 的是零开销的,我们看看具体是指什么含义。
#include <memory>
using namespace std;
struct Foo{
Foo();
~Foo();
};
void UniquePtr() {
auto p = make_unique<Foo>();
}
void RawPtr() {
auto p = new Foo();
delete p;
}
我们编译一下,然后看看生产的汇编指令
+ g++ -Os -fno-exceptions -std=c++14 -c -o unique_ptr_overhead.o unique_ptr_overhead.cpp
+ objdump -D unique_ptr_overhead.o
unique_ptr_overhead.o: file format Mach-O 64-bit x86-64
Disassembly of section __TEXT,__text:
__Z9UniquePtrv:
0: 55 pushq %rbp
1: 48 89 e5 movq %rsp, %rbp
4: 53 pushq %rbx
5: 50 pushq %rax
6: bf 01 00 00 00 movl $1, %edi
b: e8 00 00 00 00 callq 0 <__Z9UniquePtrv+0x10>
10: 48 89 c3 movq %rax, %rbx
13: 48 89 df movq %rbx, %rdi
16: e8 00 00 00 00 callq 0 <__Z9UniquePtrv+0x1b>
1b: 48 89 df movq %rbx, %rdi
1e: e8 00 00 00 00 callq 0 <__Z9UniquePtrv+0x23>
23: 48 89 df movq %rbx, %rdi
26: 48 83 c4 08 addq $8, %rsp
2a: 5b popq %rbx
2b: 5d popq %rbp
2c: e9 00 00 00 00 jmp 0 <__Z6RawPtrv>
__Z6RawPtrv:
31: 55 pushq %rbp
32: 48 89 e5 movq %rsp, %rbp
35: 53 pushq %rbx
36: 50 pushq %rax
37: bf 01 00 00 00 movl $1, %edi
3c: e8 00 00 00 00 callq 0 <__Z6RawPtrv+0x10>
41: 48 89 c3 movq %rax, %rbx
44: 48 89 df movq %rbx, %rdi
47: e8 00 00 00 00 callq 0 <__Z6RawPtrv+0x1b>
4c: 48 89 df movq %rbx, %rdi
4f: e8 00 00 00 00 callq 0 <__Z6RawPtrv+0x23>
54: 48 89 df movq %rbx, %rdi
57: 48 83 c4 08 addq $8, %rsp
5b: 5b popq %rbx
5c: 5d popq %rbp
5d: e9 00 00 00 00 jmp 0 <__Z6RawPtrv+0x31>
我们大致比较,可以那看到 make_unique
和 new/delete
编译出来了同样的指令,几乎没有区别。
同样,我们也可以看到,在空间占用上,开销也是一样的,因为 sizeof(unique_ptr<Foo>) == sizeof(Foo*)