Lin*_*umz 19 c++ stl g++ clang++ c++14
我最近开始使用C++ 14而不是C++ 11来使我的C++代码库现代化.
在用C++ 14 替换了一次std::unique_ptr.reset(new ...)
使用后std::make_unique
,我意识到我的测试套件(由大约30个C++测试程序组成)运行速度慢了约50%.
旧C++ 11代码(快速):
class Foo
{
public:
Foo(size_t size)
{
array.reset(new char[size]);
}
private:
std::unique_ptr<char[]> array;
};
Run Code Online (Sandbox Code Playgroud)
新的C++ 14代码(慢):
class Foo
{
public:
Foo(size_t size)
{
array = std::make_unique<char[]>(size);
}
private:
std::unique_ptr<char[]> array;
};
Run Code Online (Sandbox Code Playgroud)
使用C++ 14代码时,GCC和Clang都运行得慢得多std::make_unique
.当我使用valgrind测试两个版本时,它报告C++ 11和C++ 14代码使用相同数量的分配和相同数量的已分配内存,并且没有内存泄漏.
当我查看上面生成的测试程序的程序集时,我怀疑C++ 14版本std::make_unique
在使用memset分配后使用重置内存.C++ 11版本没有这样做:
C++ 11程序集(GCC 7.4,x64)
main:
sub rsp, 8
movsx rdi, edi
call operator new[](unsigned long)
mov rdi, rax
call operator delete[](void*)
xor eax, eax
add rsp, 8
ret
Run Code Online (Sandbox Code Playgroud)
C++ 14程序集(GCC 7.4,x64)
main:
push rbx
movsx rbx, edi
mov rdi, rbx
call operator new[](unsigned long)
mov rcx, rax
mov rax, rbx
sub rax, 1
js .L2
lea rax, [rbx-2]
mov edx, 1
mov rdi, rcx
cmp rax, -1
cmovge rdx, rbx
xor esi, esi
call memset
mov rcx, rax
.L2:
mov rdi, rcx
call operator delete[](void*)
xor eax, eax
pop rbx
ret
Run Code Online (Sandbox Code Playgroud)
问题:
初始化内存是一个已知的功能std::make_unique
?如果没有其他什么可以解释我遇到的性能下降?
Bar*_*rry 21
初始化内存是一个已知的功能
std::make_unique
?
这取决于你所说的"已知".但是,这是你的案件之间的区别.从cppreference,make_unique<T>(size)
调用确实:
Run Code Online (Sandbox Code Playgroud)unique_ptr<T>(new typename std::remove_extent<T>::type[size]()) // ~~~~
这是如何指定的.
new char[size]
分配内存并默认初始化它.new char[size]()
分配内存和值初始化它,在这种情况下零初始化char
.默认情况下,标准库中的许多内容将进行值初始化而不是默认初始化.
同样,make_unique<T>()
不new T()
,不new T
...... make_unique<char>()
给你0,new char
给你一个不确定的值.
作为一个类似的例子,如果我想要一个给定大小vector<char>
的未初始化缓冲区的调整大小(立即由其他东西填充),我必须使用我自己的分配器或使用不属于char
它的类型初始化.
归档时间: |
|
查看次数: |
1126 次 |
最近记录: |