当前课程知识点:软件工程 >  第2章 编写高质量代码 >  2.5 代码性能分析 >  讲课视频

返回《软件工程》慕课在线视频课程列表

讲课视频在线视频

下一节:讲课视频

返回《软件工程》慕课在线视频列表

讲课视频课程教案、知识点、字幕

效率是程序员之间永恒的话题

能够编写更快更好的代码

是我们每一个程序员不懈的追求

但实际做起来

效率优化

并不是一件很容易的事

它往往涉及到多方面的因素

在这一节课

我们将结合一个实例

介绍有关代码性能分析

和优化方面的内容

代码优化能够让程序运行的更快

它是指在不改变

程序运行结果的情况下

使得程序的运行效率更高

根据二八原则

实现程序的重构 优化 扩展

以及文档相关的事情

通常是要消耗80%的工作量

程序的性能一般涉及到

时间和空间两个方面

优化也就包括减少代码的体积

和提高代码的运行效率

这两项内容

代码性能优化

必须要在满足正确性

可靠性 健壮性 可读性

这些质量因素的前提下进行

在优化的时候

要注意从程序的全局效率

来考虑

不能单纯考虑局部

而且要先找出

限制效率的瓶颈

然后再对症下药

由于数据结构和算法

对程序效率起到关键的作用

因此优化的首要点是

数据结构和算法

其次才是执行代码

需要说明的是

时间效率和空间效率

往往是相互对立的

优化的时候

应当分析哪一个因素更重要

然后再作出适当的折中

程序性能应该在编程一开始

就要考虑进去

不要期待通过事后的调整

来进行提升

另外任何优化

都不能破坏代码的正确性

一般来说

代码优化过程包括以下步骤

首先要证明代码的性能

确实需要提升

然后要找出优化的关键部分

再通过测试

找出影响代码性能的瓶颈所在

对代码进行优化

最后还要对优化后的代码

再进行测试

以确定优化的效果

这里需要强调的是

测试数据的选择

必须能够代表实际的使用情况

另外永远不要在没有执行

前后性能评估的情况下

尝试对代码进行优化

现在我们通过一个程序示例

来详细说明代码优化的

步骤和方法

这个程序要求读入一个

文本文件

统计在该文件中

每个英文单词出现的频率

并输出频率最高的100个单词

其中单词指的是连续的

若干个小写英文字母

在这里我们给出了

几个单词的示例

像最后这一行

它是被逗号 句号 空格

分割成了四个单词

这是用Python实现的一个

程序代码例子

我们先介绍一下

它的基本结构

文件头部是关于

这个程序文件的注释

包括代码格式

作者信息等

最后两行是主程序的入口

相当于C++的main函数

文件头的下面是程序中

需要的各种包

这一部分是实现程序

主要功能的分词函数

现在我们来分析一下

分词函数中可能影响

性能的部分

第一是文件读入部分

文件的IO通常是速度比较慢的

第二是分割单词部分

这里使用了正则表达式来实现

第三是词频统计部分

我们用词典类型进行判重操作

最后是排序部分

这里使用了Python内置的

排序算法来实现

那么你认为

影响整个程序性能的

主要是哪一部分呢

是IO 单词分割 词频统计

还是排序部分

显然瞎猜是不行的

我们需要使用性能分析工具

来获得实际的测试数据

再来确定真正的性能瓶颈

Profile是Python语言内置的

性能分析工具

它能够有效地描述

程序运行时的性能状况

提供各种统计数据

帮助程序员找出程序的

性能瓶颈

Profile的使用非常简单

像图上给出的这个

求阶乘函数的例子

先在文件中引入Profile模块

再以程序的入口函数名为参数

来调用Profile.run这个函数

接下来就可以使用Profile

进行性能分析

这里显示的是Profile

对刚才那个阶乘函数

生成的测试结果报告

上面是程序的输出结果

这里呢是程序的执行时间

由于这个程序非常小

所以几乎没有什么耗时

下面是详细的函数性能

数据报表

它包括了函数被调用的次数

总的运行时间

运行一次的平均时间

以及函数所在的文件名

行号和函数名等

像这里显示了print这个函数

被调用了10次

以及其他的一些运行时间等

需要说明的是

tottime是除去了函数中

调用其他函数的总运行时间

cumtime是包括了

调用其他函数的总运行时间

二者是有区别的

现在我们来看一下

前面的词频统计程序的

性能数据报表

程序的总耗时是4.562秒

其中keys函数

被执行了50万次

耗时1.141秒

输出几乎没有耗时

输入耗时0.094秒

排序函数的耗时是1.203秒

分词函数耗时0.312秒

这些测试数据告诉我们

keys函数和排序函数的耗时

是比较多的

但是排序函数

是Python内置的函数

不容易进行优化

因此我们决定优化keys函数

这里需要说明的是

虽然性能分析工具

指明了程序各个部分的耗时

但并不意味着我们改进效率

一定要优先改进耗时

最多的部分

虽然改进耗时最多的部分

往往效果是明显的

但有的时候可能很难改进

在实际的项目中

我们需要在改进得到的效果

和改进要投入的精力之间

进行平衡

来优先完成有能力做

而且效果又比较明显的

性能优化

那么我们先分析一下

为什么keys函数的

调用复杂度这么高

经过查阅资料

我们发现keys函数每调用一次

系统就会生成一个新的

词典迭代器

如果这个过程重复50万次

那么效率是不可以想象的

所以我们提出了

一种优化的方案

就是使用in操作符

直接代替keys

然后这样就可以避免

每一次生成新的迭代器

这是改进后的程序代码

这部分就是修改的代码

我们对修改后的代码

再进行测试

那么测试结果发现

程序的总的执行时间

降低到了2.250秒

经过简单的优化

我们把程序的执行时间

从之前的4.562秒

降低到了2.250秒

差不多缩短了一半儿

这个效果还是比较明显的

这个例子告诉我们

性能优化的关键是

如何发现问题和解决问题

在这个过程中

有效的测试是不可缺少的

我们通过测试找出真正的瓶颈

并且分析优化的结果

需要注意的是

一定要避免不必要的优化

和不成熟的优化

因为不成熟的优化

有可能引来错误

最后我们针对Python代码的

性能优化

给出一些建议

仅供大家参考

首先是改进算法

并选择合适的数据结构

算法的好坏对程序的性能

是非常关键的

因为首先要改进算法的效率

在这里我们列出了算法的

时间复杂度的一个排序

想必大家在算法课程的学习中

已经有了基本的了解

对于成员的查找访问等操作

字典要比列表更快

因为Python字典中

使用了哈希表

它的查找复杂度是O(1)

而列表实际上就是一个数组

查找需要遍历整个列表

复杂度是O(n)

所以在需要多数据成员

进行频繁的查找

或者访问的时候

使用字典更好一些

集合的并 交 差的操作

比列表的迭代要快

涉及到求列表的

并 交 差问题

可以转化为集合来操作

循环优化的基本原则

是尽量减少循环中的计算量

有多重循环的时候

尽量将内层的计算提到上一层

对于字符串的优化

由于Python的字符串对象

是不可改变的

字符串的连接尽量使用

join函数

当对字符串可以使用

正则表达式或者内置函数

处理时 选择内置函数

列表解析要比在循环中

重新建一个新的列表

更为高效

因此可以利用这个特性

来提高代码的运行效率

关于代码性能优化的内容

就介绍到这里

希望大家课下

结合具体的实例

进一步地理解和实践

软件工程课程列表:

第1章 初识软件工程

-1.1 软件无处不在

--讲课视频

-1.2 软件的本质特性

--讲授视频

-1.3 软件工程的产生与发展

--讲授视频

-1.4 软件工程的基本概念

--讲授视频

-1.5 软件质量实现

--讲授视频

-1.6 业界人士谈软件工程

--海芯科技创始人施侃乐访谈

-测验题--作业

-讨论题

--讨论题

-作业题

--第一张 作业题

第2章 编写高质量代码

-2.1 编程过程与规范

--讲课视频

-2.2 良好的编程实践

--讲课视频

-2.3 Python集成开发环境

--讲课视频

-2.4 代码静态检查

--讲课视频

-2.5 代码性能分析

--讲课视频

-2.6 结对编程实践

--讲课视频

-2.7 刘贺谈软件工程

--讲课视频

--讨论

-测验题--作业

-作业题

--第二章 作业题

第3章 单元测试

-3.1 单元测试概述

--讲课视频

-3.2 黑盒测试方法

--黑盒测试方法

-3.3 白盒测试方法

--基本概念

--代码覆盖标准

--基本路径测试

-3.4 单元测试工具

--单元测试工具

--html

-测验题--作业

-作业题

--第三章 作业题

--作业题附件

第4章 软件开发过程

-4.1 软件过程

--讲课视频

-4.2 软件过程模型

--讲课视频

-4.3 敏捷开发过程

--讲课视频

-4.4 微软公司开发过程

--邹欣经理自我介绍

--微软开发过程之一

--微软开发过程之二

-测验题--作业

第5章 团队开发管理

-5.1 团队组织与管理

--讲课视频

-5.2 项目沟通管理

--讲课视频

-5.3 软件项目计划

--讲课视频

-5.4 软件项目估算

--讲课视频

-测验题--作业

-讨论题

--讨论

第6章 敏捷开发与配置管理

-6.1 敏捷开发之Scrum

-- 敏捷开发之Scrum

--html

-6.2 用户故事与估算

--讲课视频

-6.3 团队协作工具Tower

--Tower工具介绍(1)

--Tower工具介绍(2)

-6.4 配置管理

--讲课视频

-6.5 配置管理工具Git

--讲课视频

-测验题--作业

-作业题--作业

第7章 需求获取

-7.1 需求工程师

--讲课视频

-7.2 需求定义

--讲课视频

-7.3 需求的类型

--讲课视频

--讲课视频(2)

-7.4 需求工程过程

--讲课视频

-7.5 需求的主要来源

--讲课视频

-7.6 需求获取技术

--讲课视频

--讲课视频二

--讲课视频三

-7.7 撰写需求文档

--讲课视频

-测验题--作业

-讨论题

--讨论

第8章 用例建模

-8.1 用例建模概念

--讲课视频

-8.2 用例建模过程

--讲课视频

-8.3 用例建模精讲

--讲课视频

-8.4 建模工具介绍

--讲课视频

-8.5 微信抢票应用案例

--讲课视频

-测验题--作业

-讨论题

--讨论

第9章 面向对象分析与设计

-9.1 面向对象分析

--讲课视频

-9.2 CRC卡片分拣法

--讲课视频-1

--讲课视频-2

-9.3 面向对象设计

--讲课视频-1

--讲课视频-2

-9.4 类图建模

--讲课视频-1

--讲课视频-2

-第9章 面向对象分析与设计--测验题

-讨论题

--讨论

第10章 行为建模

-10.1 顺序图概念

--讲课视频

-10.2 顺序图建模

--讲课视频

-10.3 顺序图风格

--讲义视频

-10.4 状态建模

--讲课视频

-10.5 状态图

--讲课视频

-10.6 状态图精讲

--讲义视频

-测验题--作业

-讨论题

--讨论

第11章 软件系统设计

-11.1 软件体系结构概念

--讲授视频

-11.2 软件设计原则

--讲授视频

-11.3 软件体系结构风格(一)

--讲授视频

-11.4 软件体系结构风格(二)

--讲授视频

-11.5 软件体系结构风格(三)

--讲授视频

-11.6 软件设计过程

--讲授视频

-11.7 Web系统架构设计

--讲授视频

-11.8 数据库选择策略

--讲授视频

-测验题--作业

-作业题

--html

--html

--html

-作业题--作业

第12章 软件交互设计

-12.1 交互设计概述

--讲授视频

-12.2 交互设计目标

--讲授视频

-12.3 GUI设计原则

--讲课视频

-12.4 KLM效率模型

--Video

-12.5 Fitts定律

--讲授视频

-12.6 交互设计过程

--讲授视频

-测验题--作业

第13章 软件系统测试

-13.1 软件测试概念

--讲课视频

-13.2 软件测试类型

--讲课视频

-13.3 软件功能测试

--讲课视频

-13.4 软件性能测试

--讲课视频

-测验题--作业

第14章 软件交付与维护

-14.1 软件部署与交付

--讲课视频

-14.2 软件演化与维护

--讲课视频

-测验题--作业

第15章 期末考试与总结

-第一部分:基础知识

-第二部分:编程与测试(选做)

--编程与测试(选做)

讲课视频笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。