Oma*_*ser 5 c++ performance heap-memory 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;
}
Run Code Online (Sandbox Code Playgroud)
Pet*_*ker 15
new int[1e7]为1e7 int值分配空间,并且不初始化它们。
vector<int> v(1e7);vector<int>在堆栈上创建一个对象,然后该对象的构造函数为int堆上的1e7 值分配空间。它还将每个int值初始化为0。
速度差异是由于初始化。
要比较堆栈分配的速度,您需要在堆栈上分配一个数组:
int data[1e7];
Run Code Online (Sandbox Code Playgroud)
但请注意:这很有可能失败,因为堆栈不足以容纳那么大的数组。
小智 7
我只是一个初学者,但让我给出我主要了解的内容以测试自己。
在
int *p = new int[1e7];
Run Code Online (Sandbox Code Playgroud)
您正在堆上为1000万个整数分配连续的内存。
在
vector<int> v(1e7);
Run Code Online (Sandbox Code Playgroud)
您正在为vector<int>对象分配堆栈内存。在该对象的成员之间,有一个指向int[1e7]堆的指针,该指针也已分配。此外,其中的所有值均以int()(带有0s)的值初始化。参见的构造函数(2)std::vector。
其他答案指出,向量构造函数中至少有一个“隐藏”初始化。
但是您的示例还有另一个问题:也许它甚至无法衡量您的想法。在C ++中对未优化的代码进行基准测试几乎没有意义,并且很难对优化的代码进行适当的时序调整。
让我们看一下Clang编译的示例(出于可读性的考虑),其-O3优化级别为:godbolt link。
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
}
Run Code Online (Sandbox Code Playgroud)
编译为:
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
Run Code Online (Sandbox Code Playgroud)
第一部分甚至不称操作员为新!编译器浏览了您的程序并意识到您从未使用过分配的数组,因此它从生成的可执行文件中删除了分配。
因此,使用此类设置进行编译时,程序的第一部分根本不会在堆上分配数组,从而使测量变得毫无意义。
我建议阅读基准测试,并使用专门的微型基准测试框架进行此类测试。看看Google Benchmark(和在线QuickBench)及其文档。
| 归档时间: |
|
| 查看次数: |
230 次 |
| 最近记录: |