在某些情况下,我的C ++ 14程序需要大约1亿std::vector
的“块”,这需要接近1 GB的RAM。我们可以安全地假设所需的内存可用。
但是,分配新的calloc()
非常慢,因为复杂的构造函数被称为1亿次。在我的机器上,代码需要大约一整秒来初始化数组。
通过比较,调用malloc
,将分配的内存初始化为零,效果大致相同,将在很短的毫秒内运行。
事实证明,我们甚至不需要这种初始化,因为大型阵列中的复合体将很快从外部源填充。因此,我希望将“块”中对象的构造推迟到以后的时间,然后直接从外部数据源构建它们。
所以我的问题是,是否有一种安全的惯用和高效的C ++方法,或许沿途使用C ++移动语义?如果没有,我们决定简单地reinterpret_cast
内存块,那么我们可以简单complex<float>
将内存块Gridview
转换为普通的C数组吗?
感谢您的帮助
Jean-Denis Muys
答案 0 :(得分:3)
如果将complex<float>
类的默认构造函数定义为空,这会使成员变量保持未初始化,那么在打开编译器优化的情况下,两个操作之间不应该有任何真正的区别。
假设complex
类的以下定义。
template <typename T>
struct complex
{
complex() {}; // Empty constructor does nothing
T a, b;
};
在x86-64 gcc 6.2和-O2启用时使用vector
初始化生成的程序集是:
std::vector<complex<float>> v(100);
mov edi, 800
call operator new(unsigned long)
mov rdi, rax
call operator delete(void*)
生成的用于手动调用malloc
和free
的程序集为:
auto v = malloc(100 * sizeof(complex<float>));
free(v);
mov edi, 800
call malloc
mov QWORD PTR [rsp+8], rax
mov rdi, QWORD PTR [rsp+8]
call free
如您所见,vector
实现不再为每个元素调用complex<float>
的构造函数。 vector
的使用更加正确和可读,并且还利用了有助于防止内存泄漏的RAII。
答案 1 :(得分:2)
我强烈建议坚持使用c ++并避免自己手动管理内存。
标准库应该足够了。 E.g。
std::vector< complex > my_vector;
// Reserve the necessary space without constructing anything
my_vector.reserve( 100'000'000);
// construct the elements when needed
populate( my_vector );
答案 2 :(得分:0)
所以你的问题是你是否可以使用malloc()
。多年前,我使用与旧的C ++编译器相同的方法,并且它工作正常。但最后我不得不拨打free()
而不是delete[]
。我认为这是特定于实现的,因此您应该在编译器上尝试它。