C++ 性能剖析 (三):Heap Object对比 Stack (auto) Object
通常认为,性能的改进是90 ~ 10 规则, 即10%的代码要对90%的性能问题负责。做过大型软件工程的程序员一般都知道这个概念。
然而对于软件工程师来说,有些性能问题是不可原谅的,无论它们属于10%或是90%,都是“必须”改进的。这里就讲讲其中的一个问题:用heap还是用stack的问题。
Java, C#,和JavaScript的程序员一般都不用管自己创建的object是在heap里还是在stack里,因为对于这些语言,object 只能“生活在”heap里。这无疑对于程序员来说简单了许多。但是对于C++程序员来说,你可以选择三处来创建object:
- 程序的data section
- 工作堆栈
- Heap
Object 因该生活在哪里?这个问题必须由应用的属性来决定,有时是没有选择的,比如对于动态产生的全程变量,只有活在heap里,别无它途。
然而,一旦我们有选择,比如临时的,作为复杂数据的载体的object,答案是清楚的:应该首选stack. 比如下面简单的例子:
// heap vs stack test
double HeapVsStack(bool heap, int loop, int &result)
{
if (heap)
{
clock_t begin = clock();
for(int i = 0; i < loop; ++i)
{
intPair *p = new intPair(1,2);
result += p->ip1 + p->ip2;
delete p;
}
clock_t end = clock();
return double(end - begin) / CLOCKS_PER_SEC;
}
else
{
clock_t begin = clock();
for(int i = 0; i < loop; ++i)
{
intPair p = intPair(1,2);
result += p.ip1 + p.ip2;
}
clock_t end = clock();
return double(end - begin) / CLOCKS_PER_SEC;
}
}
程序中黑体放大的部分是要测量的“应用逻辑”,上方在heap中创建了一个intPair,用完后delete掉。下方在stack里定义一个同样的auto变量,用完后无须care.
对这个程序作下列简单测试调用:
int result = 0;
printf("Heap time: %f \n", HeapVsStack(true, 100000, result));
printf("Stack time: %f \n", HeapVsStack(false, 100000, result));
我不得不调用100000次,原因是它们的耗时差别实在太大了:stack 的用例不到10000次以上都显示0ms.
测试结果,heap用了300ms, stack用了5ms, 相差60倍。
结论:
1) 如果应用逻辑容许,用 stack-based auto 变量,千万不用 heap 变量.
2) 如果需要大量用heap,建议用std::vector来当作自己的 heap 简单管理器用。避免直接地,大量地用heap来创建 ad-hoc object.
3) 有些临时计算用的class可以考虑禁止在heap中生成,见http://stackoverflow.com/questions/1941517/explicitly-disallow-heap-allocation-in-c 文章。
2014-8-23 西雅图
C++ 性能剖析 (三):Heap Object对比 Stack (auto) Object的更多相关文章
- C++ 性能剖析 (一)
C++ 性能剖析 (一) 性能问题也不是仅仅用“技术”可以解决的,它往往是架构,测试,假设等综合难题.不过,对于一个工程师来说,必须从小做起,把一些“明显”的小问题解决.否则的话积小成多,千里堤坝,溃 ...
- [No0000144]深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing)理解堆与栈1/4
前言 虽然在.Net Framework 中我们不必考虑内在管理和垃圾回收(GC),但是为了优化应用程序性能我们始终需要了解内存管理和垃圾回收(GC).另外,了解内存管理可以帮助我们理解在每一个程 ...
- JVM内存模型——堆(heap)、栈(stack)和方法区(method)
JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 堆区:堆内存用于存放由new创建的对象和数组.堆是JVM管理的内存中最大的一块,堆被所有线程共享,目的 ...
- Java 堆内存与栈内存异同(Java Heap Memory vs Stack Memory Difference)
--reference Java Heap Memory vs Stack Memory Difference 在数据结构中,堆和栈可以说是两种最基础的数据结构,而Java中的栈内存空间和堆内存空间有 ...
- App架构师实践指南六之性能优化三
App架构师实践指南六之性能优化三 2018年08月02日 13:57:57 nicolelili1 阅读数:190 内存性能优化1.内存机制和原理 1.1 内存管理内存时一个基础又高深的话题,从 ...
- golang 性能剖析pprof
作为一个golang coder,使用golang编写代码是基本的要求. 能够写出代码,并能够熟悉程序执行过程中各方面的性能指标,则是更上一层楼. 如果在程序出现性能问题的时候,可以快速定位和解决问题 ...
- 快速学习C语言二: 编译自动化, 静态分析, 单元测试,coredump调试,性能剖析
上次的Hello world算是入门了,现在学习一些相关工具的使用 编译自动化 写好程序,首先要编译,就用gcc就好了,基本用法如下 gcc helloworld.c -o helloworld.o ...
- JVM的堆(heap)、栈(stack)和方法区(method)
JVM主要由类加载器子系统.运行时数据区(内存空间).执行引擎以及与本地方法接口等组成.其中运行时数据区又由方法区Method Area.堆Heap.Java stack.PC寄存器.本地方法栈组成. ...
- 堆heap和栈Stack(百科)
堆heap和栈Stack 在计算机领域,堆栈是一个不容忽视的概念,堆栈是两种数据结构.堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除.在单片机应用中,堆栈 ...
随机推荐
- centos 6.5关闭NetworkManager
jrhmpt01:/root# rpm -qa | grep -i network NetworkManager-glib-0.8.1-99.el6.x86_64 system-config-netw ...
- jQuery Validate 验证,校验规则写在控件中的具体例子
将校验规则写到控件中 <script src="../js/jquery.js" type="text/javascript"></scrip ...
- Tribles(概率)
Description Problem ATribblesInput: Standard Input Output: Standard Output GRAVITATION, n."Th ...
- 解决weblogic Managed Server启动非常慢的情况
jdk版本:1.7.0_79 查看控制台日志停留在如下地方: . . JAVA Memory arguments: -Xms2048m -Xmx4096m -XX:MaxPermSize=512m . ...
- Android 子线程请求ASP.NET后台
首先定义布局文件,及点击事件 public class MainActivity extends Activity { private final int MSG_HELLO = 0; private ...
- Eclipse的快捷键及常用设置
本篇文章转自:http://blog.csdn.net/idsunb/article/details/6604451 1.提示键配置一般默认情况下,Eclipse ,MyEclipse 的代码提示功能 ...
- Beautiful Numbers
http://codeforces.com/problemset/problem/300/C 题意:给你三个数a,b,n;求满足由a,b组成的n位的个数,且每个位置上的数之和也是用a,b组成; 解析: ...
- sl4j记录
- 缓存淘汰算法 (http://flychao88.iteye.com/blog/1977653)
1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. ...
- Mac内建Apache
打开终端 重启apache:sudo /usr/sbin/apachectl restart 关闭apache:sudo /usr/sbin/apachectl stop 开启apache:sudo ...