- 内容提要
- 前言
- 作者简介
- 封面简介
- 第1章 理解高性能 Python
- 第2章 通过性能分析找到瓶颈
- 2.1 高效地分析性能
- 2.2 Julia 集合的介绍
- 2.3 计算完整的 Julia 集合
- 2.4 计时的简单方法——打印和修饰
- 2.5 用 UNIX 的 time 命令进行简单的计时
- 2.6 使用 cProfile 模块
- 2.7 用 runsnakerun 对 cProfile 的输出进行可视化
- 2.8 用 line_profiler 进行逐行分析
- 2.9 用 memory_profiler 诊断内存的用量
- 2.10 用 heapy 调查堆上的对象
- 2.11 用 dowser 实时画出变量的实例
- 2.12 用 dis 模块检查 CPython 字节码
- 2.13 在优化期间进行单元测试保持代码的正确性
- 2.14 确保性能分析成功的策略
- 2.15 小结
- 第3章 列表和元组
- 第4章 字典和集合
- 第5章 迭代器和生成器
- 第6章 矩阵和矢量计算
- 第7章 编译成 C
- 第8章 并发
- 第9章 multiprocessing 模块
- 第10章 集群和工作队列
- 第11章 使用更少的 RAM
- 第12章 现场教训
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
7.3 为什么类型检查有助代码更快运行
Python是动态类型的——一个变量能够引用任何类型的对象,并且任意代码行都能够改变被引用对象的类型。这使得虚拟机难以在机器码层面优化代码的运行方式,因为它不知道哪种基础数据类型会用于将来的运算。让代码保持泛型就会让代码运行更慢。
在下面的例子中,v或是一个浮点数,或是一对代表复数的浮点数。两个条件会先后在相同循环的不同位置发生,或者在相关代码的串行区域发生:
v = -1.0 print type(v), abs(v) <type 'float'> 1.0 v = 1-1j print type(v), abs(v) <type 'complex'> 1.41421356237
abs函数会根据底层数据类型来以不同方式工作。对一个整数或浮点数来说,abs只是简单地把负值转换为正值来作为结果。对复数来说,abs涉及对分量的平方和开平方根:
还是复数的例子,它的机器码涉及更多的指令并且会运行得更久。在对一个变量调用abs之前,Python首先不得不查看变量的类型,接着决定调用哪个函数版本——当你做出很多重复调用的时候,这个开销会累积。
在Python的每种基础对象内部,就像integer那样,会被更高层的Python对象包装起来(例如,一个int包装了integer)。更高层的对象有额外的函数,就像为辅助存储的__hash__函数,还有为打印的__str__函数。
在CPU密集型的代码区域内部,不改变变量类型的情况很常见。这就给了我们一个机会来做静态编译和加快代码运行。
如果我们想要的一切全都是大量的中间级的数学运算,我们就不需要更高层次的函数,我们也不大可能需要引用计数的机制。我们会向下进入到机器代码的层面,并且使用机器码和字节来快速运算,而不是去操控更高层次的Python对象,那会涉及更大的开销。要做到这个,我们就要提前决定对象的类型,这样我们就能产生正确的C代码。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论