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))对数据项进行插入和删除.在单片机应用中,堆栈 ...
随机推荐
- C# Linq-Aggregate
The easiest to understand definition of Aggregate is that it performs an operation on each element o ...
- Linux企业级开发技术(7)——libevent企业级开发之锁和线程
编写多线程程序的时候,在多个线程中同时访问同样的数据并不总是安全的. libevent的结构体在多线程下通常有三种工作方式: 1.某些结构体内在地是单线程的:同时在多个线程中使用它们总是不安全的. 2 ...
- 【转】java 容器类使用 Collection,Map,HashMap,hashTable,TreeMap,List,Vector,ArrayList的区别
原文网址:http://www.360doc.com/content/15/0427/22/1709014_466468021.shtml java 容器类使用 Collection,Map,Hash ...
- adb测试使用相关
1.adb中文 无论是shell下显示中文.logcat输出中文乱码还是adb push/pull路径包括中文名,windows下都可以通过更改cmd窗口代码页为UTF-8解决: chcp 65001 ...
- MySQL客户端执行外部sql文件命令
客户端 source d:\bbs.sql 或者 \. d:\bbs.sql
- 例6.1:学生选课系统设计(界面设计、类图、数据库ER图)
- apache POI 导出excel相关方法
apache POI 操作excel无比强大.同时有操作word和ppt的接口. 下面讲解poi中常用方法. 1,设置列宽 HSSFSheet sheet = wb.getSheetAt(0); sh ...
- FusionCharts的使用入门
1. Fusioncharts 介绍: Fusioncharts是一个基于Flash的图表组件,可以用来提供数据驱动的动态图标,fusioncharts可用于任何网页脚本语言如, HTML格式,JSP ...
- jQuery Ajax 实例 具体介绍$.ajax、$.post、$.get的使用
Jquery在异步提交方面封装的非常好.直接用AJAX非常麻烦须要处理浏览器之间的兼容问题,Jquery大大简化了我们的这些操作操作.不用在考虑浏览器这方面的问题,能够直接使用! $.post.$.g ...
- Android Dialog透明度和暗度
1.设置透明度(Dialog自身的透明度)WindowManager.LayoutParams lp=dialog.getWindow().getAttributes(); lp.alpha=1.0f ...