代码揭秘第9章-瓶颈与优化
掌握如何进行代码静态分析和优化

掌握如何进行代码静态分析和优化代码静态分析和优化是软件开发中非常重要的一环,它可以帮助开发人员发现代码中的潜在问题,提高代码的质量和性能。
在这篇文章中,我将详细介绍代码静态分析和优化的相关概念、方法和工具,并分享一些实用的技巧和经验。
一、什么是代码静态分析和优化1.1代码静态分析代码静态分析是指在不执行程序的情况下对代码进行分析,以检测代码中的潜在问题和错误。
静态分析可以帮助开发人员发现潜在的安全漏洞、性能问题、不良的编程习惯等。
静态分析通常包括代码风格检查、代码规范检查、代码复杂度分析、数据流分析等。
1.2代码优化代码优化是指对代码进行改进,以提高代码的性能、可维护性和可读性。
优化可以包括优化算法、重构代码、优化数据结构、性能分析等。
优化的目标是使代码更加高效、可靠和易于维护。
二、代码静态分析的方法和工具2.1静态分析方法静态分析方法包括语法分析、语义分析、控制流分析、数据流分析等。
语法分析用于检测代码中的语法错误和语法规范是否符合要求;语义分析用于检测代码中的语义错误和逻辑错误;控制流分析用于分析代码中的控制流程是否符合预期;数据流分析用于分析代码中的数据流程是否正确。
2.2静态分析工具静态分析工具是用于实施静态分析的软件工具,包括代码检查器、静态分析器、静态代码分析工具等。
常见的静态分析工具有PMD、Checkstyle、FindBugs、Coverity、Lint等。
这些工具可以自动化地进行代码静态分析,并提供详细的分析报告和建议。
三、代码静态分析的实际应用3.1代码质量管理代码静态分析可以用于代码质量管理,帮助开发人员发现代码中的潜在问题,提高代码的质量和稳定性。
通过静态分析可以及时发现代码中的问题,避免在后期导致更严重的bug。
3.2安全漏洞检测静态分析可以用于检测代码中的安全漏洞,包括内存泄漏、空指针引用、缓冲区溢出等。
通过静态分析可以在代码提交前发现安全问题,保障软件的安全性。
3.3代码性能优化静态分析可以用于代码性能优化,通过分析代码的复杂度和执行路径,发现性能瓶颈并进行优化。
如何进行代码优化的常见技巧和方法

如何进行代码优化的常见技巧和方法随着软件和计算机在现代社会的广泛应用,代码优化已经成为了程序员不可或缺的技能。
代码优化是指通过修改代码、调整算法或使用优化工具等方法,使程序在执行时间、空间、资源利用率和可维护性等方面达到最优状态的一种技术活动。
本文将着重介绍常见的代码优化技巧和方法,以供程序员们参考和学习,以提高程序的性能和效率。
一、基础的代码优化技巧1.使用常量:将表达式中的变量替换为常量,可以大大加快程序的执行速度。
因为常量的值只需要在编译时计算一次,而变量的值需要在程序运行时计算。
2.避免重复计算:避免重复计算可以大大提高程序的效率。
例如,将计算结果存储在变量中,以便在代码中多次使用,而不是每次都重新计算。
3.使用高效的数据结构:选择正确的数据结构可以大幅提高程序的效率。
例如,对于需要插入和删除的情况,使用链表而不是数组可以更快地完成操作。
4.减少函数调用次数:函数调用往往会引起一些额外的开销,因此减少函数调用次数可以提高程序的效率。
可以通过将常用的代码作为内联函数或者使用宏定义的方式将其集成到代码中,以减少函数调用次数。
二、算法优化1.缩小搜索范围:使用二分查找、哈希表等优化算法,可以大幅提高搜索效率,特别是对于大数据集。
2.减少循环次数:使用快速排序、归并排序等高效排序算法,以减少排序时间。
并对需要循环的代码进行优化逻辑顺序,使循环次数尽可能减少。
3.使用位运算符:位运算符可以大幅提高程序的效率。
例如,使用左移位运算符代替乘法,右移位运算符代替除法等。
三、编译器优化1.使用优化编译器:优化编译器可以帮助程序员自动地进行代码优化,从而提高程序的性能。
例如,GCC编译器可以通过使用优化选项,如-O2、-O3等,增加编译器对程序的优化程度。
2.避免循环不变量:对于循环不变量,现代编译器可以自动进行优化。
然而,如果出现循环不变量在循环中被修改的情况,将影响编译器的优化效果。
四、运行时优化1.去除内存碎片:内存碎片是由于内存分配和释放之间的不规则大小和顺序造成的。
如何进行代码的优化与优化技巧

如何进行代码的优化与优化技巧随着计算机技术的发展,代码优化成为了开发人员必须掌握的重要技能之一。
在开发和维护大型软件项目时,优化代码可以提高程序的运行速度、减少内存占用和有效地利用计算资源,提高软件的性能和用户体验。
本文将介绍一些代码优化技巧,以帮助开发者提高程序的优化能力。
1.分析性能瓶颈在进行代码优化之前,最重要的一步是分析程序的性能瓶颈。
这样可以帮助开发者确定要优化哪些部分的代码,从而达到最大的效果。
可以使用一些性能分析工具,如Valgrind、gprof等,分析程序哪些部分需要优化。
2.减少函数调用函数调用是一种很方便的代码结构,但是频繁的函数调用会增加程序的运行时间,影响程序的性能。
因此,减少函数调用可以提高程序的运行速度。
可以通过以下几种方法来减少函数调用:(1)内联函数:将函数调用语句替换为函数体,可以减少函数调用所需的时间。
(2)将函数调用从循环中移出。
(3)使用函数指针,减少函数调用的次数。
3.消除无用代码在程序开发过程中,可能会出现一些无用的代码,这些代码不是必要的,但是会增加程序的复杂度,降低程序的性能。
因此,消除无用的代码可以提高程序的性能。
可以通过各种工具来消除无用代码,如GCC、Clang等。
4.减少内存分配内存分配是非常消耗资源的操作,因此减少内存分配可以提高程序的运行速度。
可以使用以下几种方法来减少内存分配:(1)使用栈上的变量。
(2)使用固定大小的缓冲区。
(3)使用对象池来分配内存。
5.避免过多的异常处理异常处理是一个很有用的特性,但是过多的异常处理会消耗大量的资源,因此可以使用以下方法避免过多的异常处理:(1)避免抛出异常。
(2)将异常处理放在尽可能小的范围内。
6.内存对齐内存对齐是一种优化内存访问的方式,可以提高程序的性能。
因为数据在内存中的存储是按照一定的规则进行的,如果一个数据的地址不是按照内存对齐的规则进行存储,那么CPU需要进行额外的运算才能访问这个数据,会降低程序的性能。
优化代码运行速度的方法与技巧

优化代码运行速度的方法与技巧优化代码运行速度是提高程序性能的重要任务之一。
下面是一些可以帮助你提升代码性能的方法和技巧。
1.选择合适的数据结构:不同的数据结构在不同的操作和查询方面有不同的效率。
选择最适合你的需求的数据结构,可以显著提高代码的性能。
2.使用更高效的算法:选择更高效的算法可以使代码更加快速和高效。
例如,排序算法的选择对性能有很大的影响。
3.减少循环次数:避免不必要的循环嵌套和重复计算。
尽量以最少的循环次数完成任务。
4.避免不必要的函数调用:函数调用时会有一定的开销。
如果可以避免不必要的函数调用,可以提高代码性能。
5.使用位运算代替乘除法运算:乘除法运算通常比位运算慢。
在合适的场景下,可以使用位运算代替乘除法运算,提高代码性能。
6.使用缓存进行优化:利用缓存机制,将频繁使用的数据存储在缓存中,减少访问内存的开销,提高代码性能。
7.避免过多的内存分配和释放:频繁的内存分配和释放会影响代码的性能。
尽量减少内存分配和释放的次数,可以使用对象池或者复用对象的方式来减少内存的开销。
8.使用并行计算:利用多线程或者并行计算框架,将计算任务分解成多个子任务并行执行,提高代码的运行速度。
9.减少磁盘和网络I/O操作:磁盘和网络I/O操作通常是程序性能的瓶颈之一。
减少对磁盘和网络的读写操作,可以提高代码的性能。
10.使用编译器优化选项:不同的编译器有不同的优化选项,可以根据编译器的不同选择合适的优化选项,提高代码的性能。
11.减少异常的使用:异常处理会有一定的开销。
在合适的场景下,可以减少异常的使用,提高代码性能。
12.使用缓存优化数据库操作:频繁的数据库查询和更新会影响代码的性能。
可以使用缓存机制来减少对数据库的访问,提高代码性能。
13.避免过度优化:过度的代码优化可能会导致代码复杂度增加,可读性和可维护性下降。
在优化代码时,需要平衡代码性能和代码质量之间的关系。
总结起来,优化代码运行速度需要考虑多个因素,包括选择合适的数据结构和算法、减少不必要的循环和函数调用、使用位运算和缓存优化、并行计算、减少磁盘和网络I/O操作等。
数据库性能调优中的瓶颈定位与解决方法

数据库性能调优中的瓶颈定位与解决方法在进行数据库性能调优时,识别和解决瓶颈是一个至关重要的步骤。
数据库瓶颈会导致性能下降,影响应用程序的响应时间,降低用户体验。
本文将介绍数据库性能调优中常见的瓶颈,并提供相应的解决方法,帮助您更好地优化数据库性能。
一、磁盘IO瓶颈磁盘IO瓶颈是数据库性能调优中经常遇到的问题。
它指的是当数据库需要大量的读写操作时,磁盘无法以足够高的速度响应请求,导致性能下降。
下面是一些解决磁盘IO瓶颈的方法:1. 使用RAID技术:RAID可以将多个磁盘组合成一个逻辑磁盘,从而提高数据的读写速度和容错能力。
常见的RAID级别有RAID 0、RAID 1、RAID 5等,根据应用需求选择合适的RAID级别。
2. 使用SSD磁盘:相比于传统的机械磁盘,固态硬盘(SSD)具有更快的读写速度和更低的延迟。
将数据库的存储设备替换为SSD磁盘可以显著提高数据库的性能。
3. 使用分区和索引:通过将数据分成较小的块并使用索引进行访问,可以减少对磁盘的IO操作,提高数据库的查询和更新性能。
二、查询优化瓶颈查询是数据库最常见的操作,但是不正确的查询方式和缺乏优化可能导致性能下降。
以下是一些解决查询优化瓶颈的方法:1. 使用合适的索引:索引可以加快查询速度,但是过多或者过少的索引都会对数据库性能产生负面影响。
根据实际查询需求和数据分布情况,选择合适的索引来优化查询性能。
2. 避免全表扫描:全表扫描是指没有使用索引,而是对整个表进行扫描的查询操作。
全表扫描通常会导致性能下降,尽量避免全表扫描,使用索引来加速查询。
3. 使用合适的算法:对于一些复杂的查询,选择适当的算法可以提高查询性能。
例如,对于大数据集合的连接操作,可以考虑使用哈希连接或者排序合并连接来加快查询速度。
三、内存不足瓶颈数据库的内存不足可能导致瓶颈,因为内存是数据库缓存和执行查询所需的关键资源。
以下是一些解决内存不足瓶颈的方法:1. 增加内存容量:将更多的内存分配给数据库,可以提高缓存的效果,降低磁盘IO的需求,从而提高查询和更新操作的性能。
优化代码的常用方法和策略

优化代码的常用方法和策略优化代码是编程中非常重要的一项技能,通过优化代码可以提高程序的执行效率和性能。
下面将介绍一些常用的优化代码的方法和策略。
1. 减少循环次数:- 避免不必要的循环,例如可以通过更简单的算法或逻辑来减少循环次数。
- 尽量避免嵌套循环,可以通过将一些内层循环提取到外层循环中来减少循环次数。
2. 使用更高效的数据结构和算法:- 选择合适的数据结构,例如使用散列表(哈希表)可以加快查找操作的速度。
- 尽量使用高效的算法,例如使用快速排序算法替代冒泡排序算法。
3. 减少内存分配:- 避免频繁的内存分配和释放,可以通过使用对象池或缓存来减少内存分配次数。
- 尽量使用栈变量代替堆变量,因为栈变量的分配和释放速度更快。
4. 避免过多的函数调用:- 函数调用会引入额外的开销,尤其是对于频繁调用的函数。
可以通过将一些短小的函数内联展开,减少函数调用的开销。
5. 使用延迟计算:- 避免在不必要的情况下进行计算,可以通过延迟计算的方式来避免重复计算或者不需要的计算。
6. 使用并发编程:- 对于可以并行执行的任务,可以使用并发编程来提高程序的执行效率。
- 可以使用多线程或多进程来同时处理多个任务,充分利用多核处理器的性能。
7. 进行代码剖析和性能测试:- 可以使用工具来分析代码的性能瓶颈,并找出需要优化的部分。
- 在进行代码优化之前,首先要了解哪些部分是性能瓶颈,才能有针对性地进行优化。
8. 使用适当的编译器选项:- 在编译代码时,可以使用一些编译器选项来优化代码的生成。
- 例如使用优化选项可以使得编译器能够对代码进行更好的优化。
9. 避免重复计算:- 在代码中避免重复计算相同的结果,可以通过缓存中间结果来避免重复计算。
10. 利用硬件特性:- 可以针对具体的硬件特性进行优化,例如利用SIMD指令集进行向量化计算,提高代码执行的并行度。
通过以上的一些常用的方法和策略,可以对代码进行优化,提高程序的执行效率和性能。
代码优化的思路和方法

代码优化的思路和方法代码优化的思路和方法随着计算机技术的不断进步,越来越多的人开始接触和使用计算机。
从简单的算数计算到更复杂的程序设计,计算机在各个领域都有着广泛的应用。
而在编写程序的过程中,代码优化问题成为了一个非常重要的话题。
代码优化能够提高程序的效率,减少系统资源的消耗,提高程序的运行速度,降低出错的风险,从而让程序能够更加稳定和可靠地运行。
本篇文章将介绍代码优化的思路和方法,旨在帮助读者更好地了解和掌握代码优化技术。
一、什么是代码优化代码优化是一种改善程序性能和减少程序资源的消耗的技术。
代码优化能够降低程序的开销,使其更有效率运行。
它主要是通过修改代码,使之更加精简和高效,从而达到提高程序性能的目的。
代码优化在程序开发过程中是一项非常重要的任务。
一个优化良好的程序能够处理更多的数据量,更快地运行,同时也可以减少所占用的系统资源。
例如,一个优化良好的程序能够更快地完成排序、搜索和过滤等操作,提高工作效率,节省时间和金钱。
二、代码优化的思路代码优化的思路主要包括以下几个方面:1.采用适当的数据结构在编写程序的过程中,采用恰当的数据结构非常重要。
例如,当需要对一个大型数据集进行排序时,使用二叉树进行排序会比使用简单数组等数据结构更有效率。
2.将多个语句合并为一个语句很多时候,我们可能会写出很多重复的语句,这样会增加程序运行的时间。
如果能将这些语句合并为一个语句,就能够减少代码的行数,并提高程序的执行效率。
3.减少变量的使用在编写程序的过程中,我们应该尽量减少变量的使用。
变量的定义和赋值操作需要占用系统资源。
在一些简单的情况下,我们可以使用常量代替变量,减少变量的定义和赋值操作。
4.减少函数调用当程序执行函数调用时,程序需要进行额外的操作,这样会增加程序的开销。
因此,在编写程序的过程中,我们应尽量减少函数的调用。
5.减少循环的使用循环是一种常见的程序结构,但循环的使用会导致程序的执行时间变长。
当处理大量数据时,可以使用其他更有效的方法,例如map、reduce等,来减少循环的使用。
Java编程技巧:优化算法提升程序性能

Java编程技巧:优化算法提升程序性能在Java编程中,性能是一个关键的问题。
随着软件和系统的复杂度增加,我们需要不断优化我们的代码以提高程序的性能。
其中一个重要的方面是优化算法。
在本文中,我将与您分享一些Java编程技巧,以帮助您优化算法并提升程序性能。
为什么优化算法对性能至关重要?在编程中,算法是解决问题的步骤和规则的集合。
一个优化的算法可以显著提高程序的执行效率,从而减少运行时间和资源消耗。
相比之下,一个低效的算法可能会导致程序运行得非常缓慢,并占用大量内存和CPU资源。
通过优化算法,我们可以使程序更加高效地执行任务,同时减少对计算资源的需求。
这对于开发大规模的系统或处理大量数据的应用程序至关重要。
Java编程中常见的性能瓶颈在优化算法之前,我们需要先了解一些常见的性能瓶颈,这些瓶颈可能会导致程序运行缓慢。
以下是一些常见的性能瓶颈:1.循环和迭代循环和迭代是Java编程中常见的操作。
然而,如果循环过于复杂或不必要地重复执行,可能会导致程序性能下降。
在编写循环和迭代代码时,务必要注意循环次数和循环体内的操作。
2.递归递归是一种函数调用自身的技术。
虽然递归可以解决一些问题,但它也可能导致性能问题。
递归函数调用本身是一项昂贵的操作,特别是当使用大量递归调用时。
3.内存管理Java由于具有自动内存管理机制(垃圾收集器),开发人员可以不必手动释放内存。
然而,不合理的内存使用可能导致内存泄漏和性能下降。
确保及时释放不再使用的对象,并避免创建过多的临时对象。
4.字符串操作字符串操作在Java编程中很常见。
然而,由于字符串是不可变的,每次执行字符串操作(如连接、替换等)时,都会创建一个新的字符串对象。
这会占用大量的内存和处理时间。
使用StringBuilder或StringBuffer类来处理频繁的字符串操作可以提高性能。
5.IO操作IO操作通常是一个耗费资源的操作。
在处理大量数据或频繁进行IO操作时,务必注意优化IO代码以提高性能。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
本书名称:代码揭秘-从c/c++的角度探秘计算机系统作者:左飞第9章瓶颈与优化——论立于此,若射之有的也,或百步之外,或五十步之外,的必先立,然后挟弓注矢以从之即使程序编码工作已经完成,程序员可以做的事情仍然很多。
如果你有很好的数据结构知识并为程序设计了比较好的算法,然后你也掌握了计算机系统运行的机制,理解了编译器的行为,并尽你所能地以贴近这些原理的方式去书写代码,而结果你也无法绝对避免出现纰漏。
因为实际项目往往非常庞大!许多细小的问题在产生之初并不为人所重视,当程序逐渐丰满起来后,原来的“小问题”所造成的影响就可能被放大,这就是所谓的“蝴蝶效应”。
特别是在许多这样的小问题的共同作用下,最终影响的程度可能令人无法估计。
这时,你就必须找出程序运行的瓶颈并优化具体的代码,这是一项非常有意义的事情。
但让一个能够正确工作的程序变得高效却也不是一件容易的事情。
首先,程序员必须准确地发现程序效率不高的症结所在。
然而在浩如烟海的代码中寻找这样的“症结”犹如大海捞针,谈何容易?做到最优往往是不可能的,但依然可以在有限的范围内逼近最优。
特别值得庆幸的是,通过一些既有的技术手段,尽可能地优化代码在目前看来其可行性是很高的!本章就来讨论这方面的一些话题,并给出在实际中可操作的一些方法。
第9章瓶颈与优化第一章绪论9.1 优化还是不优化现在我们要讨论的一个问题是如何使程序运行得更快。
但必须说明的是,极致的效率并不是实际中一个程序的最重要属性!通常,程序员更关心的事情是如何开发出易于编写、调试和维护的程序,有谁会为了一些看似并不明显的效率改进而绞尽脑汁地去琢磨一些数据结构和算法方面的难题呢。
下面这三点原则支持了上述观点。
首先,一个正确的程序,即使它的效率不高,计算出正确结果的时间也要比一个不正确的程序所耗用的时间短。
因此如果一个算法能够保证程序可靠地运行,那么就使用它吧,尽管它是一个简单却效率不高的算法。
Bruce Eckel在其著名的《Thinking in C++》一书中有一句话是这样说的:“First make it work, then make it fast.”,翻译过来就是,首先使其能够正常工作,然后再考虑将其优化。
所以如何写一个正确的程序才是最重要的!其次,一个完成的程序,计算出正确结果的时间总要比一个还在开发的程序所耗用的时间短。
开发高效程序的时间往往较长,甚至有可能当开发成功时,它们也已经不再被需要了。
《庄子》记叙了这样一则故事——“周昨来,有中道而呼者。
周顾视,车辙中有鲋鱼焉。
周问之曰:‘鲋鱼来!子何为者邪?’对曰:‘我,东海之波臣也。
君岂有斗升之水而活我哉?’周曰:‘诺,我且南游吴越之王,激西江之水而迎子,可乎?’鲋鱼忿然作色曰:‘吾失我常与,我无所处。
吾得斗升之水然活耳。
君乃言此,曾不如早索我于枯鱼之肆!’”意思是说——庄子路上遇到一条鲫鱼在沟里喊救命,庄子答应它去请吴越国君放西江之水救它,鱼儿怒道:我现在有斗升之水就可救命,你这样说,还不如早早到咸鱼店去见我呢!类比于我们所说的程序设计问题,我们应该明白已经完成的程序才是可用的程序,把希望寄托于一个想象中的程序是不切实际的。
再举个并不一定恰当的例子(但这个例子仍然能够很明了地解释这种观点)。
众所周知,绝对意义上安全的密码是不存在的。
一个安全的密码只是指在信息有效期内无法被破译的密码。
如果说被加密的信息有效期是五十年,而破解它的密码却需要五百年,那么这个密码就是安全的,因为即使五百年后密码被成功破解了,这个密码也已经没有任何实际价值了。
如果我们花费很长的时间去开发一个高效的程序,就有可能出现同样的结果,即程序开发成功了,它也没有用武之地了。
最后,目前计算机的速度大约每18个月就翻一番。
计算机技术发展如此的迅速,以至于效率上的提高往往是通过等待下一代硬件的出现来实现的。
如果一个用户使用的是一款交互式设置的程序(目前几乎所有的程序都是交互式的),那么由于人机界面设计上的一些结果,可能会使得用户在交互的过程中,几乎不能感觉到那些由于算法优化而被提升的效率,至少这种331◎代码揭秘332 感觉不如直接升级硬件来得强烈。
举个例子来说:一个不需要交互的程序,例如,计算一个高精度的圆周率值(如保留小数点后面一千万位有效数字),这时程序是否从设计和编码角度被优化,人们的感觉会非常强烈。
因为在这漫长的计算过程中,人机之间缺乏交互,只需要输入一个初始状态,然后计算机就会按照既定的算法开始计算,直到得到结果后输出,用户对于这个过程的长短非常敏感。
但是,在通常情况下,目前一个用户所使用的程序都不是这样的,例如,在Windows环境下安装一个软件的过程,用户总是要单击许多回“下一步”按钮,时不时地还需要输入一些信息。
那么从单击一回“下一步”按钮到单击下一回“下一步”按钮的过程中,计算机也使用了一些算法来执行这个过程,这种情况下,我们费尽心机地来优化程序编码以使其效率有所提高,可能这种微量级的改进,用户根本就体会不到。
因为用户单击两回“下一步”按钮之间必然存在一定的时间间隔,即使程序很快就算完了,它也不得不等待用户单击“下一步”按钮后才能做进一步的工作,而它到底算没算完,算了多长时间,用户则毫无察觉。
对于这种情况,优化似乎没有多大意义。
上面的观点非常实际而且较为客观!但这是不是就说明程序的优化是毫无意义的呢?当然不是。
假设你编写了一个结构清晰、便于编码且易于维护的程序,但它的效率却很低,甚至令人无法忍受,那该怎么办呢?是置之不理、无动于衷吗?前面的观点固然正确,但它们也都是有适用范围的。
首先,一个能够正常运行而且可靠的程序固然好,但是如果一个能够正常运行且可靠的程序,其运行效率还非常高,那就更好了!其次,有些优化并非要依赖于费心琢磨复杂的算法和数据结构,这些优化往往依赖于一些经验、训练、培养及技术手段。
习惯于写出高效代码的程序员并不一定都是算法专家,但他们一定有良好的编码习惯和实践经验。
最后,某些编码工作的确要求程序员精于代码优化!一个极端的例子是,如果你从事与科学计算有关的工作,很可能某一天你的工作就是写一个程序计算圆周率小数点后面的第五百万位!撇开这种极端情况不谈,如果你的工作是编写Matlab这样的数学计算软件或者是像Photoshop这样的数字图像处理软件呢?这总还是有可能的吧。
要知道图像处理对于效率的要求可是非常高的!再比如说,万一你真的水平太差,编出来的程序在相邻的两次单击“下一步”按钮操作之间的等待时长有一炷香那么久,那试问谁会去买你的软件呢?综上所述,基本的程序优化依然是必要的!那么如何优化呢?通常,程序优化有一套可以遵循的一般步骤,它们可以用于指导实际的程序优化流程。
首先,你要理解是什么使你的程序变慢的。
程序的大部分运行时间被用在何处?如果程序的大部分运行时间都用在了少数几个地方,那么这就为大幅度优化提供了可能。
第9章瓶颈与优化第一章绪论然后,设计并实现一个方法来使你的程序用最少的努力来获得最大的速度。
这个所谓的“方法”有可能是设计一个高效的算法,也可能只是在发现为什么程序如此慢的基础上做一些技术层面的调整。
而所谓的高效算法事实上也并不一定像想象中的那样复杂,它也可能仅仅是在原来代码的基础上所作的一些微调,但可千万别小看这些微调!最后,反复迭代地使用前面两步,直到程序的性能达到要求或者剩余的优化工作得不偿失为止。
9.2 测量与分析的内容为了回答是什么使你的程序变慢以及程序的大部分运行时间被用在何处这两个问题,我们必须能够定量地考察程序的运行状况。
这时读者可能会想到时间复杂度的大O表示法,但那不是我们所需要的。
注意:时间复杂度的分析仅仅是定性地考察一个程序的复杂情况,而这种定性的结果往往和实际情况有一定距离。
例如,同样用于字符串匹配的KMP算法和BM算法具有相同的理论时间复杂度,但大量实验和数据表明BM算法的实际效率要远高于KMP算法。
在明确如何从技术角度去研究定量地分析程序代码运行效率这个问题之前,首先要知道分析的对象和内容是什么。
没有实际测量一个工作中的程序就试图优化它是一个非常不明智的选择。
这也就是为什么说在开发期间尽量不要做太多的优化工作的原因,因为你有可能花费了许多时间来优化错误的东西(如果你感到必须早些优化,那你就做一些小测试来使你自己确信优化的确有必要)。
为了准确地定量给出程序的实际运行效率,最常需要测量的量就是CPU时间。
CPU时间就是处理器用来执行指令的时间,它不会将那些用于执行其他程序的时间和用于等待的时间计算在内。
除此之外,另一个可以用来定量评估程序的实际运行效率的量就是实际时间,也称作挂钟时间(“wall clock time”或“wall time”)。
挂钟时间就是指使用普通的钟表或者腕表来测量程序运行而得到的时长。
为什么一个程序执行的CPU时间和挂钟时间不同?众所周知,尽管从宏观上看我们所使用的PC都是“多程序并行”及“资源共享”的,但从微观上看所使用的系统都是“分时”且“资源独享”的。
来解释一下上面这句话的意思。
说所使用的PC系统是“多程序并行”及“资源共享”的,那是因为从宏观上来看,用户可以一边进行文字处理工作,一边听音乐,同时还开着杀毒程序进行全盘扫描。
似乎这些工作都各自运行正常且不相互影响,因为在你编辑文字时,音乐并没有时断时续,杀毒程序也一直在工作,系统资源好像被这些程序所共享着。
但从微观上来看,事实并非如此!因为我们知道CPU每次只能执行一条指令,所以所使用的PC系333◎代码揭秘334 统只不过是一个“分时”的系统。
系统把资源按照时间片分成一个个微小的单元,在某一时刻,这些资源仅被某一个程序所独享。
由于时间片非常微小,以至于宏观上用户都毫无察觉。
CPU 时间就是以系统最小的时间片为单位,精准地记录了CPU执行仅属于该程序的那些指令所耗用的时间。
而如果使用普通的计时器来记录一个程序的运行时长,那么所得到的挂钟时间往往包含了一些其他工作所耗用的时间。
CPU 时间和挂钟时间的差值能够给出一些暗示,这些信息揭示了程序用于等待I/O所花费的时间。
就以CPU 时间本身而言,它可以被分成用户时间与系统时间两部分,用户时间就是那些被直接地用来执行程序员所编写的程序代码的时间,而系统时间则是由操作系统代表你的程序所耗用的时间。
因为一个使用高级语言编写的程序之所以能够运行起来,往往离不开操作系统的支持,程序的许多代码调用了操作系统的API,而操作系统则负责更加底层的工作和调度以满足程序运行的实际需求。
无论是CPU时间还是挂钟时间,对于评估一个程序的实际运行状况都是有意义的。
无论是系统时间还是用户时间,所有的这些时间的测量工作都将帮助开发人员理解当程序执行时,程序的内部到底发生了什么,它们共同作用揭示了许多底层的问题,这对于提高程序运行效率,优化代码编写具有重要的意义。