`

主题:减少变量实例化次数有多大作用

阅读更多

在JE上看到了一个帖子讨论下面这种代码的优化问题的:

C代码 复制代码
  1. int main(int argc, char *argv[])   
  2. {   
  3.     int i;   
  4.     for (i = 0; i < 20000; i++) {   
  5.         int j;   
  6.         for (j = 0; j < 2000; j++) {   
  7.             int k;   
  8.             for (k = 0; k < 200; k++);   
  9.         }   
  10.     }   
  11.     return 0;   
  12. }  
int main(int argc, char *argv[])
{
	int i;
	for (i = 0; i < 20000; i++) {
		int j;
		for (j = 0; j < 2000; j++) {
			int k;
			for (k = 0; k < 200; k++);
		}
	}
	return 0;
}



显然是在考查要把循环次数少的放在外层,理由是这样可以减少变量实例话的次数。原理如此,我只是想更加清楚地知道这样做有多大的作用,于是我用gcc的profile工具测试了一下。

把上面的代码用 gcc -pg 编译,profile结果显示整个程序用时32.68秒,多次运行有不到0.1秒的浮动误差。

如果改成

C代码 复制代码
  1. int main(int argc, char *argv[])   
  2. {   
  3.     int i;   
  4.     for (i = 0; i < 200; i++) {   
  5.         int j;   
  6.         for (j = 0; j < 2000; j++) {   
  7.             int k;   
  8.             for (k = 0; k < 20000; k++);   
  9.         }   
  10.     }   
  11.     return 0;   
  12. }  
int main(int argc, char *argv[])
{
	int i;
	for (i = 0; i < 200; i++) {
		int j;
		for (j = 0; j < 2000; j++) {
			int k;
			for (k = 0; k < 20000; k++);
		}
	}
	return 0;
}


用时32.20秒,效率大约提升了1.5%。

以上并没有使用编译器自身的优化选项。下面来看看如果使用了 gcc -O3 (第三级优化)编译会有什么样的结果。
结果表明有很大的改观:前者用时5.07秒,后者用时4.54秒。

如果启用了 -O9 最高级别的优化,后者用时4.60秒,前者用时5.12秒,可见 -O9 并不比 -O3 强。

别忘了这里面的循环要执行 200*2000*20000 = 8000000000,80亿次!即使不用编译器优化,那种被认为是“低效率”的代码也可以32秒多执行完,而那种“高效率”的代码不过把时间减少了1.5%。在实际情况下,调整内外循环顺序可能会严重降低代码的可读性。

而只是简单地加了一个编译器优化,立刻就能把速度提高5倍多。人脑终归不能像编译器一样理解代码。

 

此文转自: http://www.iteye.com/topic/762637

分享到:
评论

相关推荐

    Java基础Note——流程语句及方法和数组

    流程语句及方法和数组 流程语句 Switch switch语句选择的基本数据类型只有byte,short,char,int。没有long并且支持的引用类型都是以上四个基本数据类型的包装类, java5和7后支持枚举和String类。...减少实例化次数

    如何利用Java开发高性能、高并发Web应用

    此外,我们还可以讨论优化循环体的另一个技巧,即使用循环变量来减少循环次数。例如,我们可以将for循环改写为:for(int i = 0,j = 10; i ; i++,j--){ if(j == 0){ ... // 每十次执行一次 j = 10;}} 这样可以减少...

    P2P视频播放器 详细制作实例

    2) 使用maxid来减少搜索次数. 在TCP中没有使用Hash, 使用了maxid这一项, 用来记录Session中最大的id, 由于在Session 初始化的时候, 是查找ID最小的空闲Session, 因此可以认为Session是比较紧凑的, 由于SP和CP支持的...

    代码优化:有效使用内存.part3

    1.6.8第八步:减少内存访问操作的次数 1.6.9第九步:把VTune当做私人教练 1.6.10第十步:下结论 1.6.11结果与预测 第2章RAM子系统 2.1RAM概述 2.2RAM的层次结构 2.3随机存取存储器 2.4RAM的设计与工作原理 2.4.1内核...

    代码优化:有效使用内存.part2

    1.6.8第八步:减少内存访问操作的次数 1.6.9第九步:把VTune当做私人教练 1.6.10第十步:下结论 1.6.11结果与预测 第2章RAM子系统 2.1RAM概述 2.2RAM的层次结构 2.3随机存取存储器 2.4RAM的设计与工作原理 2.4.1内核...

    代码优化:有效使用内存.part1

    1.6.8第八步:减少内存访问操作的次数 1.6.9第九步:把VTune当做私人教练 1.6.10第十步:下结论 1.6.11结果与预测 第2章RAM子系统 2.1RAM概述 2.2RAM的层次结构 2.3随机存取存储器 2.4RAM的设计与工作原理 2.4.1内核...

    Java面试宝典2010版

    18、一个用户表中有一个积分字段,假如数据库中有100多万个用户,若要在每年第一天凌晨将积分清零,你将考虑什么,你将想什么办法解决? 19、一个用户具有多个角色,请查询出该表中具有该用户的所有角色的其他用户。...

    最新Java面试宝典pdf版

    18、一个用户表中有一个积分字段,假如数据库中有100多万个用户,若要在每年第一天凌晨将积分清零,你将考虑什么,你将想什么办法解决? 107 19、一个用户具有多个角色,请查询出该表中具有该用户的所有角色的其他...

    零起点学通C++多媒体范例教学代码

    10.3.2 成员变量的初始化与构造函数 10.3.3 复制构造函数 10.3.4 构造函数和new运算符 10.3.5 再谈默认构造函数 10.4.析构函数和delete运算符 10.4..1 默认析构函数 10.4.2 调用构造函数进行类型转换 10.5 浅层复制...

    python cookbook(第3版)

    1.1 解压序列赋值给多个变量 1.2 解压可迭代对象赋值给多个变量 1.3 保留最后N个元素 1.4 查找最大或最小的N个元素 1.5 实现一个优先级队列 1.6 字典中的键映射多个值 1.7 字典排序 1.8 字典的运算 1.9 ...

    Java面试笔试资料大全

    18、一个用户表中有一个积分字段,假如数据库中有100多万个用户,若要在每年第一天凌晨将积分清零,你将考虑什么,你将想什么办法解决? 107 19、一个用户具有多个角色,请查询出该表中具有该用户的所有角色的其他...

    零起点学通C++学习_多媒体范例教学代码

    10.3.2 成员变量的初始化与构造函数 10.3.3 复制构造函数 10.3.4 构造函数和new运算符 10.3.5 再谈默认构造函数 10.4.析构函数和delete运算符 10.4..1 默认析构函数 10.4.2 调用构造函数进行类型转换 10.5 ...

    VISUAL BASIC 编程标准

    全书配有大量应用实例,便于读者学以致用。本书适用于Visual Basic 编程人员,对于使用其他语言的编程人员,也有很高的参考价值。 目 录 译者序 前言 第一部分 设 计 第1章 创建对象和工程模板 1 1.1 使用对象模板...

    java面试题大全(2012版)

    18、一个用户表中有一个积分字段,假如数据库中有100多万个用户,若要在每年第一天凌晨将积分清零,你将考虑什么,你将想什么办法解决? 107 19、一个用户具有多个角色,请查询出该表中具有该用户的所有角色的其他...

    整理后java开发全套达内学习笔记(含练习)

    序列化,串行化 ['siәriәlaiz]'(serializable adj.)(deserialize反序列化,反串行化) Socket [java] 网络套接字['sɒkit] stack n.堆栈 [stæk] (对应 heap 堆) statement 程序语句; 语句 ['steitmәnt]' n. 陈述,...

    Java面试宝典-经典

    18、一个用户表中有一个积分字段,假如数据库中有100多万个用户,若要在每年第一天凌晨将积分清零,你将考虑什么,你将想什么办法解决? 107 19、一个用户具有多个角色,请查询出该表中具有该用户的所有角色的其他...

    JAVA面试宝典2010

    18、一个用户表中有一个积分字段,假如数据库中有100多万个用户,若要在每年第一天凌晨将积分清零,你将考虑什么,你将想什么办法解决? 107 19、一个用户具有多个角色,请查询出该表中具有该用户的所有角色的其他...

    java面试宝典2012

    18、一个用户表中有一个积分字段,假如数据库中有100多万个用户,若要在每年第一天凌晨将积分清零,你将考虑什么,你将想什么办法解决? 117 19、一个用户具有多个角色,请查询出该表中具有该用户的所有角色的其他...

    Java面试宝典2012版

    18、一个用户表中有一个积分字段,假如数据库中有100多万个用户,若要在每年第一天凌晨将积分清零,你将考虑什么,你将想什么办法解决? 107 19、一个用户具有多个角色,请查询出该表中具有该用户的所有角色的其他...

Global site tag (gtag.js) - Google Analytics