为什么分配堆内存比分配堆栈记忆更快
Why is allocating heap-memory much faster than allocating stack-memory?
我试图在堆中分配10^7个整数的空间,以查看哪一个更快。显然,在堆内存中分配要快得多,但我不明白原因。
#include <bits/stdc++.h>
#include <chrono>
using namespace std;
using namespace std::chrono;
int main()
{
high_resolution_clock::time_point t1 = high_resolution_clock::now();
int *p = new int[1e7];
high_resolution_clock::time_point t2 = high_resolution_clock::now();
auto duration = duration_cast<microseconds>( t2 - t1 ).count();
cout << duration / 1e6 << "n"; // 5e-06
t1 = high_resolution_clock::now();
vector<int> v(1e7);
t2 = high_resolution_clock::now();
duration = duration_cast<microseconds>( t2 - t1 ).count();
cout << duration / 1e6 << "n"; // 0.112284
return 0;
}
new int[1e7]
为1e7 int
值分配空间,而不会初始化它们。
vector<int> v(1e7);
在堆栈上创建一个vector<int>
对象,该对象的构造函数分配了堆上1E7 int
值的空间。它也初始化每个int
值为0。
速度的差异是由于初始化。
要比较堆栈中需要分配数组的堆栈速度:
int data[1e7];
但要警告:很有可能会失败,因为堆栈还不够大,以使其大。
我只是一个初学者,但让我主要理解的是要测试自己。
在
中int *p = new int[1e7];
您将在堆上为1000万个整数分配连续内存。
在
中vector<int> v(1e7);
您是在堆栈内存上分配vector<int>
对象。在该对象的成员中,有一个指向堆上int[1e7]
的指针,也分配了。此外,其中所有值都以int()
的值(带0s(初始化。请参阅std::vector
的构造函数(2(。
其他答案指出,向量构造函数中至少有一个"隐藏"初始化。
但是您的示例有另一个问题:也许它甚至无法衡量您的想法。C 中的基准不优化的代码几乎毫无意义,并且正确定时优化代码很难。
让我们看一下您的(修改以获取可读性的(示例,由Clang和-O3
优化级别:Godbolt链接。
double test1() {
high_resolution_clock::time_point t1 = high_resolution_clock::now();
int *p = new int[1e7];
high_resolution_clock::time_point t2 = high_resolution_clock::now();
auto duration = duration_cast<microseconds>( t2 - t1 ).count();
return duration / 1e6; // 5e-06
}
编译为:
test1(): # @test1()
push rbx
call std::chrono::_V2::system_clock::now()
mov rbx, rax
call std::chrono::_V2::system_clock::now()
sub rax, rbx
movabs rcx, 2361183241434822607
imul rcx
mov rax, rdx
shr rax, 63
sar rdx, 7
add rdx, rax
cvtsi2sd xmm0, rdx
divsd xmm0, qword ptr [rip + .LCPI0_0]
pop rbx
ret
.LCPI1_0:
.quad 4696837146684686336 # double 1.0E+6
第一部分甚至不会致电新运营商!编译器浏览了您的程序,并意识到您从未使用过分配的数组,因此它从结果可执行文件中删除了分配。
因此,您程序的第一部分在编译以下设置时完全不会在堆上分配数组。
我建议阅读有关基准测试的信息,并使用专门的微型基准框架进行此类测试。查看Google基准测试(和在线QuickBench(及其文档。
我想注意,堆栈分配在运行时绝对没有时间;所有工作都是由编译器完成的。无论优化如何,比较都是没有意义的。
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- 为什么分配堆内存比分配堆栈记忆更快
- 当记忆分配给课堂时
- 如何为标准功能分配空间并做记忆
- 如何在函数中分配的自由记忆
- 我怎么知道std :: vector的分配记忆大小
- 参考记忆分配技术
- C++的记忆分配困境