堆区?栈区?速度差异到底有多少

本文档的出发点

堆与栈的概念与异同点,不打算赘述,因为已经有太多相关文章了,本文档以定量化的形式展示与对比堆区与栈区速度上的差异,随便聊聊,希望可以为大家后续的学习与工作,起到一定的帮助作用。

由于自己近期在做效率优化相关的工作,像彻底的深挖下堆区与栈区的区别,探讨下是否会启发效率优化的工作。但是随着自己翻阅了众多的技术文章,发现一个问题,很多文章都是定性的阐述了基本概念,相信对面试会有很大辅助。这些文章基本都可以总结为以下,对两者的几点差异点总结如下:

变量可分配空间 大,基于虚拟内存
分配速度
访问速度
维护 难,麻烦 自动释放

所以,其中关于访问速度查到的都是定性的论断,慢,到底慢多少?我想知道具体的差异,因此决定还是亲历亲为,自己测试下。


运行环境

项目
编译器 MSVC
系统 Windows 10
芯片 Intel
内存 8GB
支持指令 CPUZ 实测支持 SSE、SSE2等
线程 单线程

测量方法

1、以微妙级别统计时间函数 QueryPerformanceCounter 进行测量,官方介绍如下:

QueryPerformanceCounter function - Win32 apps​docs.microsoft.com/zh-cn/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter?redirectedfrom=MSDN正在上传…重新上传取消​

2、每次循环 1000000 次,取均值进行对比;

3、测量函数自己封装一层,所以当本身时间运行很短时,会有 overhead;


测量结果

  1. 每个人的测试环境一定不一样,这里给出的结果,大家可以看其相对值,有个大体概念;
  2. 精力有限,只测试乘法,其它如加法、乘累加、偏移、标量乘等未测;
  3. 取6组长度,均取以2底的指数,因为信号处理领域FFT的缘故,经常出现此类长度;
  4. 为了区分读与写的速度差异,如下分为四组,比如 stack*heap->heap,就表示该乘法中,第一个变量表示源自栈区,第二个变量源自堆区,写入地址为堆区,其他表示方法以此类推。

乘法速度测试结果,单位微秒:

stack*stack->stack heap*heap->heap stack*heap->heap stack*heap->stack
64 1.1 1.1 1.1 1.1
256 1.1 1.2 1.2 1.1
1024 1.1 1.8 1.7 1.1
4096 1.2 4.1 3.6 1.2
16384 1.7 13.0 11.0 1.7
65536 3.5 49.3 3.5 41.2

结论

1、通过典型的 stack*heap->heap 这一组可以发现,当前软硬环境下,堆区和栈区对于的速度已经几乎不敏感,重点在于对内存的速度上了。

2、随着向量长度的增加,四者运算时间差异显著拉大,原因自己还没有探究明白,不知是否因为内存不连续导致

3、所以如果代码中有大量频繁的写操作,建议将对应内存开辟在栈上,应该可以大幅度优化效率。

 

上一篇:栈的基础概念与经典题目(Leetcode题解-Python语言)


下一篇:ctfshow pwn pwn02 同时也作为入门题目无比细致讲解分析 真0基础入门