听说Python比较慢,这是怎么回事?_惠州计算机Python培训学校
作者:黄君发布时间:2021-05-21分类:惠州计算机学校浏览:910
在速度上,Java如何同C,C++,C#或者Python相比较?答案几乎完全取决于要运行的应用。在这个问题上,没有完美的评判标准,然而The Computer Language Benchmarks Game 是一个不错的方法。
链接:
http://benchmarksgame.alioth.debian.org
基于我对The Computer Language Benchmarks Game超过十年的观察,相比于Java,C#,Go,JavaScript, C++等,Python是最慢的语言之一。其中包括了 JIT (C#, Java) 和 AOT (C, C++)编译器,以及解释型语言,例如JavaScript。
动态编译:
https://en.wikipedia.org/wiki/Just-in-time_compilation
静态编译:
https://en.wikipedia.org/wiki/Ahead-of-time_compilation
注意:当我提到“Python”时,我指的是CPython这个官方的解释器。我也将在本文中提及其他的解释器。
我想要回答这样一个问题:当运行同一个程序时,为什么Python会 比其他语言慢2到10倍?为什么我们无法将它变得更快?
以下是最主要的原因:
“它是GIL(Global Interpreter Lock全局解释器锁)”
“它是解释型语言而非编译语言”
“它是动态类型语言”
那么以上哪种原因对性能影响最大呢?
“它是全局解释器锁”
现代计算机的CPU通常是多核的,并且有些拥有多个处理器。为了充分利用多余的处理能力,操作系统定义了一种低级的结构叫做线程:一个进程(例如Chrome浏览器)可以产生多个线程并且指导内部系统。
如果一个进程是CPU密集型,那么其负载可以被多核同时处理,从而有效提高大多数应用的速度。
当我写这篇文章时,我的Chrome浏览器同时拥有44个线程。注意,基于POSIX(比如MacOS和Linux)和Windows操作系统相比,线程的结构和API是不同的。操作系统也会处理线程的调度问题。
如果你之前没有做过多线程编程,你需要快速熟悉锁的概念。区别于单线程进程,你需要确保当内存中的变量被修改时,多线程不会同时试图访问或者改变同一个存储地址。
当CPython创建变量时,它会预先分配存储空间,然后计算当前变量的引用数目。这个概念被称为引用计数。如果引用计数为零,那么它将从系统中释放对应存储区域。
这就是为什么在CPython中创造“临时”变量不会使应用占用大量的存储空间——尤其是当应用中使用了for循环这一类可能大量创建“临时”变量的结构时。
当存在多个线程调用变量时,CPython如何锁住引用计数成为了一个挑战。而“全局解释锁”应运而生,它能够谨慎控制线程的执行。无论有多少的线程,解释器每次只能执行一个操作。
这对Python的性能意味着什么呢?
如果你的应用基于单线程、单解释器,那么讨论速度这一点就毫无意义,因为去掉GIL并不会影响代码性能。
如果你想使用线程在单解释器(Python 进程)中实现并发,并且你的线程为IO密集型(例如网络IO或磁盘IO),你就会看到GIL争用的结果。
如果你有一个网络应用(例如Django)并且使用WSGI,那么每一个对于你的网络应用的请求将是一个独立的Python解释器,因此每个请求只有一个锁。因为Python解释器启动很慢,一些WSGI便集成了能够使保持Python进程的“守护进程” 。
那么其他Python解释器的速度又如何呢?
PyPy拥有GIL,通常比CPython快至少三倍。
Jython没有GIL,因为在Jython中Python线程是用Java线程表示的,这得益于JVM内存管理系统。
JavaScript是如何做到这一点的呢?
首先,所有的Javascript引擎使用标记加清除的垃圾收集系统,而之前提到GIL的基本诉求是CPython的存储管理算法。
JavaScript没有GIL,但因为它是单线程的,所以也并不需要GIL。
JavaScript通过事件循环和承诺/回调模式来实现异步编程的并发。Python有与异步事件循环相似的过程。
“因为它是解释型语言”
我经常听到这句话。我觉得这只是对于CPython实际运行方式的一种简单解释。如果你在终端中输入python myscript.py,那么CPython将对这段代码开始一系列的读取,词法分析,解析,编译,解释和运行。
这个过程中的重要步骤是在编译阶段创建一个.pyc 文件,这个字节码序列将被写入Python3下__pycache__/ 路径中的一个文件(对于Python2,文件路径相同)。这个步骤不仅仅应用于脚本文件,也应用于所有导入的代码,包括第三方模块。
所以大多时候(除非你写的代码只运行一次),Python是在解释字节码并且本地执行。下面我们将Java和C#.NET相比较:
Java编译成一门“中间语言”,然后Java虚拟机读取字节代码并即时编译为机器代码。.NET的通用中间语言(CIL)是一样的,它的通用语言运行时间(CLR)也采用即时编译的方法转化为机器代码。
那么,如果Python用的是和Java和C#一样的虚拟机和某种字节代码,为什么在基准测试中它却慢得多?首先,.NET和Java是采用JIT编译的。
JIT,又称即时编译,需要一种中间语言来把代码进行分块(或者叫数据帧)。预编译(AOT, Ahead of Time)器的设计保证了CPU能够在交互之前理解代码中的每一行。
JIT本身不会使执行速度更快,因为它仍然执行相同的字节码序列。但是,JIT允许在运行时进行优化。好的JIT优化器可以检测哪些部分执行次数比较多,这些部分被称为“热点”。然后,它将用更高效的代码替换它们,完成优化。
这就意味着当计算机应用程序需要重复做一件事情的时候,它就会更加地快。另外,我们要知道Java和C#是强类型语言(变量需要预定义),因此优化器可以对代码做更多的假设。
PyPy使用即时编译器,并且前文也有提到它比CPython更快。这篇关于基准测试的文章介绍得更为详细——什么版本的Python最快?
链接:
https://hackernoon.com/which-is-the-fastest-version-of-python-2ae7c61a6b2b
那么,为什么CPython不使用即时编译器呢?
JIT存在一些缺点:其中一个是启动时间。CPython启动时间已经相对较慢,PyPy比CPython还要慢2-3倍。众所周知,Java虚拟机的启动速度很慢。为了解决这个问题,.NET CLR在系统启动的时候就开始运行,但CLR的开发人员还开发了专门运行CLR的操作系统来加快它。
如果你有一个运行时间很长的Python进程,并且其代码可以被优化(因为它包含前文所述的“热点”),那么JIT就能够起到很大作用。
但是,CPython适用于各类应用。因此,如果你使用Python开发命令行应用程序,每次调用CLI时都必须等待JIT启动,这将非常缓慢。
CPython必须尽量多地尝试不同的案例以保证通用性,而把JIT插入到CPython中可能会让这个项目停滞不前。
如果你想要借助JIT的力量,而且你的工作量还比较大,那么使用PyPy吧。
“因为它是一个动态类型语言”
在静态类型语言中,定义变量时必须声明类型。C, C++, Java, C#, Go都是这种语言。
在动态类型语言中,类型的概念依旧存在,但是这个变量的类型是动态变化的。
a = 1a = "foo"
在上面这个例子中,Python创建第二个变量的时候用了同样的名字,但是变量类型是str(字符型),这样就对先前在内存中给a分配的空间进行了释放和再分配。
静态类型语言的这种设计并不是为了麻烦大家——它们是按照CPU的运行方式设计的。如果最终需要将所有内容都转化为简单的二进制操作,那就必须将对象和类型转换为低级数据结构。
Python自动完成了这个过程,我们看不见,也没必要看见。
不必声明类型不是使Python变慢的原因。Python语言的设计使我们几乎可以创建任何动态变量。我们可以在运行时替换对象中的方法,也可以胡乱地把低级系统调用赋给一个值。几乎怎么修改都可以。
正是这种设计使得优化Python变得异常困难。
为了阐明我的观点,我将使用一个MacOS中的应用。它是一个名为Dtrace的系统调用跟踪工具。CPython发行版没有内置DTrace,因此你必须重新编译CPython。以下演示中使用3.6.6版本。
wget https://github.com/python/cpython/archive/v3.6.6.zipunzip v3.6.6.zipcd v3.6.6./configure --with-dtracemake
现在python.exe将在整条代码中使用Dtrace跟踪器。Paul Ross就Dtrace做了一篇很棒的短演讲。 你可以下载Python的DTrace启动文件来测试函数调用、执行时间、CPU时间、系统调用等各种有意思的事情。例如:
sudo dtrace -s toolkit/<tracer>.d -c ‘../cpython/python.exe script.py’
DTrace启动文件:
https://github.com/paulross/dtrace-py/tree/master/toolkit
演讲链接:
https://github.com/paulross/dtrace-py#the-lightning-talk
py_callflow跟踪器显示应用程序中的所有函数调用
因此,是Python的动态类型让它变慢的吗?
比较和转换类型是耗时的,因为每次读取、写入变量或引用变量类型时都会进行检查
很难优化一种如此动态的语言。其他语言之所以那么快是因为他们牺牲了一定的灵活性,从而提高了性能。
了解一下Cython,它结合了C-Static类型和Python来优化已知类型的代码,可以提供84倍速度的性能提升。
结论
Python的缓慢主要是由于它动态和多用途的特点。它可以用于解决几乎所有问题,但是更加优化而快捷的替代方案可能存在。
但是,有一些方法可以通过利用异步计算,理解分析工具,以及考虑使用多个解释器来优化Python应用程序。
对于有些启动时间相对不重要,并且即时编译器(JIT)可以提高效率的应用,可以考虑使用PyPy。
对于性能优先并且有更多静态变量的代码部分,请考虑使用Cython.
点击咨询直接了解更多相关资料,我在惠州北大青鸟新方舟等你。
本文内容转载自网络,版权归原作者所有,如有侵权请联系我们进行删除。
标签:惠州计算机软件培训惠州计算件软件开发惠州计算机软件基础惠州计算机Python软件开发惠州Python培训学校惠州Python培训python基础教程python是什么python教程python入门
- 惠州计算机学校排行
- 标签列表
-
- Java (3694)
- 北大青鸟 (3713)
- 软件开发 (3613)
- JAVA (3413)
- UI设计入门 (2093)
- 惠州北大青鸟 (4375)
- 惠州IT培训 (2558)
- UI设计培训 (2090)
- 惠州UI设计培训 (2095)
- 惠州UI设计培训学校 (2090)
- 惠州计算机软件培训 (6260)
- 惠州计算件软件开发 (6260)
- 惠州计算机软件基础 (6261)
- 惠州计算机JAVA培训 (3574)
- 惠州计算机Java软件开发 (3620)
- 惠州计算机JAVA软件开发 (4645)
- 惠州计算机JAVA软件开发学校 (3338)
- 惠州计算机Java软件开发培训 (3338)
- 北大青鸟IT计算机学校 (5048)
- 北大青鸟IT软件学校 (5062)
- 北大青鸟IT学校 (5059)
- 惠州计算机UI设计软件开发 (2088)
- UI设计基础教程 (2088)
- UI设计是什么 (2088)
- UI设计教程 (2088)
- 网站分类
-
- 计算机教程
- 计算机入门
- 职业学校
- 新闻动态
- 专业课程
- 热门技术
- SEO
- 培训教程
- windows
- linux教程
- 系统集成
- 网站开发
- Html5
- 办公软件
- 师资力量
- 热点问答
- 联系我们
- 计算机学校
- 惠州计算机学校
- 河源计算机学校
- 广州计算机学校
- 深圳计算机学校
- 湛江计算机学校
- 佛山计算机学校
- IT计算机培训信息
- 设计专业
- UI
- 影视特效
- 游戏动漫设计
- Photoshop
- AI设计
- 软件教程
- Java技术
- C语言/C++语言培训
- C#
- Python技术
- PHP
- 数据库
- SQL Server
- 网络教程
- 网络安全
- 网络营销
- 软件专业
- 大数据专业
- 前端开发专业
- 软件测试专业
- Python专业
- 软件实施
- 珠海计算机学校
- 初中生学什么好
- 计算机认证
- 文章归档
-
- 2024年12月 (15)
- 2024年11月 (45)
- 2024年10月 (32)
- 2024年9月 (29)
- 2024年8月 (68)
- 2024年7月 (59)
- 2024年6月 (43)
- 2024年5月 (48)
- 2024年4月 (80)
- 2024年3月 (65)
- 2024年2月 (54)
- 2024年1月 (25)
- 2023年12月 (12)
- 2023年11月 (73)
- 2023年10月 (134)
- 2023年9月 (34)
- 2023年8月 (3)
- 2023年7月 (3)
- 2023年6月 (12)
- 2023年5月 (30)
- 2023年4月 (72)
- 2023年3月 (11)
- 2023年2月 (34)
- 2023年1月 (37)
- 2022年12月 (78)
- 2022年11月 (359)
- 2022年6月 (1193)
- 2022年5月 (570)
- 2022年4月 (1567)
- 2022年3月 (982)
- 2022年2月 (54)
- 2022年1月 (182)
- 2021年9月 (308)
- 2021年8月 (1704)
- 2021年7月 (2423)
- 2021年6月 (1806)
- 2021年5月 (1569)
- 2021年4月 (1380)
- 2021年3月 (1255)
- 2021年2月 (709)
- 2021年1月 (1521)
- 2020年12月 (3626)
- 2020年11月 (1646)
- 2020年10月 (1046)
- 2020年9月 (592)
- 最近发表
-
- 东莞信息:2024年长安镇技能创业咖啡节成功举办|||广州计算机软件培训
- 河源信息:本周六百企万岗职等你来市县镇联动大型招聘活动即将开幕!|||计算机培训学校招生
- 茂名信息:茂名组织劳动人事仲裁案件庭审观摩活动|||大学生计算机培训学校
- 茂名信息:茂名市人力资源和社会保障局相继开展诚信宣传四进主题实践活动|||广州市北大青鸟计算机职业培训学校
- 茂名信息:凝心聚力共筑平安茂名市人力资源和社会保障局开展平安建设暨一感两度宣传活动|||大学生计算机培训学校
- 汕头信息:汕头市人力资源和社会保障局开展宪法宣传周活动|||北大青鸟计算机培训中心
- 梅州信息:梅州市人社局开展2024年第四季度诚信文化主题宣传志愿服务活动|||电脑计算机编程培训学校
- 东莞信息:塘厦人社分局联合消防大队开展技工学校等机构消防安全培训|||广州计算机软件培训
- 东莞信息:塘厦塘厦镇成功举办优才服务区第二期业务提升培训班|||计算机软件培训学校
- 东莞信息:2024年横沥镇举办模具设计师职业技能大赛|||广州计算机软件培训