通常认为,性能的改进是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的更多相关文章

  1. C++ 性能剖析 (一)

    C++ 性能剖析 (一) 性能问题也不是仅仅用“技术”可以解决的,它往往是架构,测试,假设等综合难题.不过,对于一个工程师来说,必须从小做起,把一些“明显”的小问题解决.否则的话积小成多,千里堤坝,溃 ...

  2. [No0000144]深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing)理解堆与栈1/4

    前言   虽然在.Net Framework 中我们不必考虑内在管理和垃圾回收(GC),但是为了优化应用程序性能我们始终需要了解内存管理和垃圾回收(GC).另外,了解内存管理可以帮助我们理解在每一个程 ...

  3. JVM内存模型——堆(heap)、栈(stack)和方法区(method)

      JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 堆区:堆内存用于存放由new创建的对象和数组.堆是JVM管理的内存中最大的一块,堆被所有线程共享,目的 ...

  4. Java 堆内存与栈内存异同(Java Heap Memory vs Stack Memory Difference)

    --reference Java Heap Memory vs Stack Memory Difference 在数据结构中,堆和栈可以说是两种最基础的数据结构,而Java中的栈内存空间和堆内存空间有 ...

  5. App架构师实践指南六之性能优化三

    App架构师实践指南六之性能优化三 2018年08月02日 13:57:57 nicolelili1 阅读数:190   内存性能优化1.内存机制和原理 1.1 内存管理内存时一个基础又高深的话题,从 ...

  6. golang 性能剖析pprof

    作为一个golang coder,使用golang编写代码是基本的要求. 能够写出代码,并能够熟悉程序执行过程中各方面的性能指标,则是更上一层楼. 如果在程序出现性能问题的时候,可以快速定位和解决问题 ...

  7. 快速学习C语言二: 编译自动化, 静态分析, 单元测试,coredump调试,性能剖析

    上次的Hello world算是入门了,现在学习一些相关工具的使用 编译自动化 写好程序,首先要编译,就用gcc就好了,基本用法如下 gcc helloworld.c -o helloworld.o ...

  8. JVM的堆(heap)、栈(stack)和方法区(method)

    JVM主要由类加载器子系统.运行时数据区(内存空间).执行引擎以及与本地方法接口等组成.其中运行时数据区又由方法区Method Area.堆Heap.Java stack.PC寄存器.本地方法栈组成. ...

  9. 堆heap和栈Stack(百科)

    堆heap和栈Stack 在计算机领域,堆栈是一个不容忽视的概念,堆栈是两种数据结构.堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除.在单片机应用中,堆栈 ...

随机推荐

  1. C# Linq-Aggregate

    The easiest to understand definition of Aggregate is that it performs an operation on each element o ...

  2. Linux企业级开发技术(7)——libevent企业级开发之锁和线程

    编写多线程程序的时候,在多个线程中同时访问同样的数据并不总是安全的. libevent的结构体在多线程下通常有三种工作方式: 1.某些结构体内在地是单线程的:同时在多个线程中使用它们总是不安全的. 2 ...

  3. 【转】java 容器类使用 Collection,Map,HashMap,hashTable,TreeMap,List,Vector,ArrayList的区别

    原文网址:http://www.360doc.com/content/15/0427/22/1709014_466468021.shtml java 容器类使用 Collection,Map,Hash ...

  4. adb测试使用相关

    1.adb中文 无论是shell下显示中文.logcat输出中文乱码还是adb push/pull路径包括中文名,windows下都可以通过更改cmd窗口代码页为UTF-8解决: chcp 65001 ...

  5. MySQL客户端执行外部sql文件命令

    客户端 source d:\bbs.sql 或者 \.  d:\bbs.sql

  6. 例6.1:学生选课系统设计(界面设计、类图、数据库ER图)

  7. apache POI 导出excel相关方法

    apache POI 操作excel无比强大.同时有操作word和ppt的接口. 下面讲解poi中常用方法. 1,设置列宽 HSSFSheet sheet = wb.getSheetAt(0); sh ...

  8. FusionCharts的使用入门

    1. Fusioncharts 介绍: Fusioncharts是一个基于Flash的图表组件,可以用来提供数据驱动的动态图标,fusioncharts可用于任何网页脚本语言如, HTML格式,JSP ...

  9. jQuery Ajax 实例 具体介绍$.ajax、$.post、$.get的使用

    Jquery在异步提交方面封装的非常好.直接用AJAX非常麻烦须要处理浏览器之间的兼容问题,Jquery大大简化了我们的这些操作操作.不用在考虑浏览器这方面的问题,能够直接使用! $.post.$.g ...

  10. Android Dialog透明度和暗度

    1.设置透明度(Dialog自身的透明度)WindowManager.LayoutParams lp=dialog.getWindow().getAttributes(); lp.alpha=1.0f ...