加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 移动互联 > 正文

你知道为什么Python这么慢?

发布时间:2018-10-29 21:42:45 所属栏目:移动互联 来源:Anthony Shaw
导读:Python 现在越来越火,已经迅速扩张到包括 DevOps、数据科学、Web 开发、信息安全等各个领域当中。 然而,相比起 Python 扩张的速度,Python 代码的运行速度就显得有点逊色了。 在代码运行速度方面,Java、C、C++、C# 和 Python 要如何进行比较呢?并没有

即时Just-in-time(JIT)编译需要一种中间语言,以便将代码拆分为多个块(或多个帧)。而提前ahead of time(AOT)编译器则需要确保 CPU 在任何交互发生之前理解每一行代码。

JIT 本身不会使执行速度加快,因为它执行的仍然是同样的字节码序列。但是 JIT 会允许在运行时进行优化。一个优秀的 JIT 优化器会分析出程序的哪些部分会被多次执行,这就是程序中的“热点”,然后优化器会将这些代码替换为更有效率的版本以实现优化。

这就意味着如果你的程序是多次重复相同的操作时,有可能会被优化器优化得更快。而且,Java 和 C# 是强类型语言,因此优化器对代码的判断可以更为准确。

PyPy 使用了明显快于 CPython 的 JIT。更详细的结果可以在这篇性能基准测试文章中看到:哪一个 Python 版本最快?。

那为什么 CPython 不使用 JIT 呢?

JIT 也不是完美的,它的一个显著缺点就在于启动时间。 CPython 的启动时间已经相对比较慢,而 PyPy 比 CPython 启动还要慢 2 到 3 倍。Java 虚拟机启动速度也是出了名的慢。.NET CLR 则通过在系统启动时启动来优化体验,而 CLR 的开发者也是在 CLR 上开发该操作系统。

因此如果你有个长时间运行的单一 Python 进程,JIT 就比较有意义了,因为代码里有“热点”可以优化。

不过,CPython 是个通用的实现。设想如果使用 Python 开发命令行程序,但每次调用 CLI 时都必须等待 JIT 缓慢启动,这种体验就相当不好了。

CPython 试图用于各种使用情况。有可能实现将 JIT 插入到 CPython 中,但这个改进工作的进度基本处于停滞不前的状态。

如果你想充分发挥 JIT 的优势,请使用 PyPy。

是因为 Python 是一种动态类型的语言吗?

在 C、C++、Java、C#、Go 这些静态类型语言中,必须在声明变量时指定变量的类型。而在动态类型语言中,虽然也有类型的概念,但变量的类型是可改变的。

  1. a = 1
  2. a = "foo"

在上面这个示例里,Python 将变量 a 一开始存储整数类型变量的内存空间释放了,并创建了一个新的存储字符串类型的内存空间,并且和原来的变量同名。

静态类型语言这样的设计并不是为了为难你,而是为了方便 CPU 运行而这样设计的。因为最终都需要将所有操作都对应为简单的二进制操作,因此必须将对象、类型这些高级的数据结构转换为低级数据结构。

Python 也实现了这样的转换,但用户看不到这些转换,也不需要关心这些转换。

不用必须声明类型并不是为了使 Python 运行慢,Python 的设计是让用户可以让各种东西变得动态:可以在运行时更改对象上的方法,也可以在运行时动态添加底层系统调用到值的声明上,几乎可以做到任何事。

但也正是这种设计使得 Python 的优化异常的难。

为了证明我的观点,我使用了一个 Mac OS 上的系统调用跟踪工具 DTrace。CPython 发布版本中没有内置 DTrace,因此必须重新对 CPython 进行编译。以下以 Python 3.6.6 为例:

  1. wget https://github.com/python/cpython/archive/v3.6.6.zip
  2. unzip v3.6.6.zip
  3. cd v3.6.6
  4. ./configure --with-dtrace
  5. make

这样 python.exe 将使用 DTrace 追踪所有代码。Paul Ross 也作过关于 DTrace 的闪电演讲。你可以下载 Python 的 DTrace 启动文件来查看函数调用、执行时间、CPU 时间、系统调用,以及各种其它的内容。

  1. sudo dtrace -s toolkit/<tracer>.d -c ‘../cpython/python.exe script.py’

py_callflow 追踪器显示了程序里调用的所有函数。

那么,Python 的动态类型会让它变慢吗?

  • 类型比较和类型转换消耗的资源是比较多的,每次读取、写入或引用变量时都会检查变量的类型
  • Python 的动态程度让它难以被优化,因此很多 Python 的替代品能够如此快都是为了提升速度而在灵活性方面作出了妥协
  • 而 Cython 结合了 C 的静态类型和 Python 来优化已知类型的代码,它可以将性能提升 84 倍。

总结

由于 Python 是一种动态、多功能的语言,因此运行起来会相对缓慢。对于不同的实际需求,可以使用各种不同的优化或替代方案。

例如可以使用异步,引入分析工具或使用多种解释器来优化 Python 程序。

对于不要求启动时间且代码可以充分利用 JIT 的程序,可以考虑使用 PyPy。

而对于看重性能并且静态类型变量较多的程序,不妨使用 Cython。

【责任编辑:庞桂玉 TEL:(010)68476606】
点赞 0

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读