第12章 提升性能所需编码准则

12.1 重视性能,限制输出

启动Linux操作系统的计算机时,会看到很多提示信息。虽然初衷是为了输出必要信息,但反复输出相同信息反而会成为一种负担。因此,最好支持用户可以自由设置程序运行时是否输出提示信息。也就是说,用户可以选择输出或不输出这些信息。

用户不满意的地方远不止这些输出信息。C语言中,负责格式化输出的printf()函数的运算成本要远高于其他运算。因为将字符串按照一定格式转换为数字的过程非常复杂,而且将字符输出到标准输出设备的过程同样非常耗时。另外,涉及这一过程的scanf()或sscanf()函数的运算成本也非常高。


printf()函数的运算成本接近加法运算成本的200倍!

12.2 用简单形式改写运算表达式

C编译器处理运算的成本:
位运算、逻辑运算 < 加法运算 < 乘法运算 < 除法运算 < 处理浮点数

所以运算时,应该尽可能选择成本较低的运算。

12.3 需要高效处理大文件时应使用二进制文件

用C语言处理文件时,一般使用ASCII格式的文件。

ASCII格式编写的文件优点是,在任何地方都可以查看该文件,因为任何计算机都提供可以查看ASCII格式文件的命令或程序。而且便于一直,Windows上编写的ASCII文件可以直接用于Linux。

但是,ASCII文件的读写速度要低于二进制文件,而且所占空间更大。因此,如果程序性能至关重要或需要节约存储空间,最好选用二进制文件而非ASCII文件。

12.4 了解并使用压缩/未压缩结构体优缺点

C语言擅长信号处理。实际生活中,随处可见需要信号处理的情况。用网络连接的计算机之间需要进行各种信号往来,根据TCP、IP或ICMP、UDP等规则传送或接收信号。

C语言中,一般将负责这种信号处理的函数编写为结构体形式,使用更加方便。实际上,大部分程序员会单独定义负责信号处理的数据类型,即设置用户自定义数据类型。大部分程序员会用结构体声明这种数据类型。下列示例声明用户自定义数据类型Siganl。

struct Signal {
    char input_character;
    int error_check;
    // …略…
    int parity_check;
    int carrier_check;
    int power_check;
}

假设int型大小为4字节,整个结构体为17字节。假设有需要同时处理1万个信号的极端程序,则声明的数组整体大小为17万个字节,约等于170kB。有的操作系统限制栈大小为64kB。也就是说,栈无法容纳该数组,需要寻找解决方案。

第一个解决方案是将数组声明为静态变量。但这并不是正确的解决方法,因为定义为静态变量可能扰乱整个程序流程。

第二个解决方案是减少Signal大小。如何减少呢?大部分信号只表现on/off。因此,可以用位域定义组成该数据类型的个元素。如下示例所示:

struct Signal {
    char input_character;
    int error_check:1;
    int parity_check:1;
    int carrier_check:1;
    int power_check:1;
}

像这样,用位域定义负责信号处理的各元素后,Signal总大小减少到2字节之内。因此,即使声明10000个信号处理所需数组,也只需要20000字节,即20kB。这就满足一部分操作系统关于“栈最大为64kB”的限制。

这种使用位域减少所占空间大小的结构体又称压缩结构体。为了节约内存空间,信号处理领域多采用压缩结构体。但压缩结构体会减慢程序运行速度,因为位域运算需要消耗大量时间。

两种结构体各有利弊。程序员应该充分认识这一点,并根据不同情况做出选择。

12.5 根据运行环境选择编程语言

C++、Java、C#运行环境

凭心而论,与C++相比,Java和C#更易掌握,也更稳定。而且Java和C#实现了网络环境下的优化。网络中的各计算机的操作系统可能各不相同,即使如此,只要安装JVM或CLR这种虚拟运行环境,即可随时运行Java和C#编写的程序。

正因为Java和C#编写的程序并不依赖计算机操作系统,而需要经过JVM或CLR这一步骤,所以运行速度慢。但C和C++在网络环境下相对有些力不从心。

C++是在C语言种引入面向对象的概念形成的,而Java则在C++中引入混合方式编译器这一构想,C#与Java相似却更简便、更稳定

可能有人会质疑,选择与运行环境相吻合的语言和编码风格有什么关系呢?其实,编码风格的第一步就是选择编程语言。选择何种编程语言对程序的影响程度远大于缩进等细枝末节的影响。

12.6 根据情况选择手段

指针可以大幅提高程序性能,所以市面上的图书常常将擅长使用指针的程序员吹捧为“高级程序员”“有能力的程序员”。编写组成嵌入式系统的程序时,需要程序能够优化系统。而嵌入式系统相对缺少大型内存、CPU的支持,必须考虑效率的问题。这种情况下,能够随心所欲地熟练使用指针地程序员一定会备受推崇。

那么,编写个人PC或企业服务器上运行地程序时,对效率没有极端要求。在这种情况下,能够选择与业务情况、系统情况相吻合的恰当方法处理问题的程序员跟为可贵。例如,在需要最大限度保证可移植性的情况下,即使运行速度减慢、占用内存变多、代码编写更为繁琐,也应该选择数组而非指针,应该选择值传递而非引用传递。

简而言之,擅长使用指针的人不一定时能者。能够从语言提供的各种工具中选择最合适的,并知道如何充分利用该工具才最重要。

12.7 选择更优秀的数据结构

有时,需要处理的数据太多,超出数组可以承受的范围,此时应该选择数组以外的其他数据结构,其中以使用链表为最优。但这并不意味着数组只有缺点没有优点。处理字符串这种较小的数据或数据个数极少时,数组更为方便,即便于处理又便于理解。

因此,应该根据情况选择合适的数据结构。本书之所以介绍这种理论性的内容是因为,众多程序员居然选择利用数组解决所有问题,而不根据情况选择合适的数据类型。有些程序员甚至不知道除数组外还有其他数据结构。

不同程序员可能会用各种方式实现相同的程序设计,此时,数据结构应用能力的高低决定了编程质量的优劣。例如,在没有任何具体排序方式要求的情况下,收到实现排序功能的需求时,程序员可以自由选择排序方式。此时,选用不同的数据结构决定了排序方式和排序性能,所以必须对数据结构由充分认识。最好选择与情况相吻合的数据结构,无论数组、链表、树、队列、栈还是其他数据结构都有各自的优缺点,需要综合考虑并作出最优选择。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,103评论 1 32
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,746评论 0 10
  • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
    夏天再来阅读 3,345评论 0 2
  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,319评论 0 9
  • 计算机系统漫游 代码从文本到可执行文件的过程(c语言示例):预处理阶段,处理 #inlcude , #defin...
    willdimagine阅读 3,586评论 0 5