千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:沈阳千锋IT培训  >  技术干货  >  为什么python这么慢

为什么python这么慢

来源:千锋教育
发布人:xqq
时间: 2023-11-12 02:12:59

Python越来越受欢迎。它被用于DevOps、数据科学、Web开发和安全。

然而,它并没有赢得任何速度奖牌。

就速度而言,Java与C或c++或c#或Python相比如何?

答案在很大程度上取决于您正在运行的应用程序的类型。没有一个基准测试是完美的,但是计算机语言基准测试游戏是一个很好的起点。

十多年来,我一直在参考计算机语言基准测试游戏;与其他语言如Java、c#、Go、JavaScript、c++相比,Python是最慢的语言之一。这包括JIT(c#,Java)和AOT(C,c++)编译器,以及解释语言,如JavaScript。

注:当我说“Python”时,我指的是该语言的参考实现CPython。Python是一门语言,有语法等规范。但是落实到具体实现上,就不一样了。用C实现的叫CPython,也是目前的参考实现。即最新的语言特性都是在这个上面先实现,Linux,OSX等自带的也是这个版本。用.NET实现的叫IronPython,Java的叫Jython,用Python实现的叫PyPy

我想回答这个问题:当Python比另一种语言慢2-10倍完成一个可比较的应用程序时,为什么它慢,我们不能使它更快?

以下是最热门的理论:

它是GIL(全局解释器锁)"因为它是解释过的而不是编译过的因为它是动态类型语言

这些原因中哪一个对性能影响最大?

我们逐个分析

1.它是GIL(全局解释器锁)

现代计算机的CPU是多核的,有时也有多个处理器。为了利用所有这些额外的处理能力,操作系统定义了一个称为线程的底层结构,其中一个进程(如Chrome浏览器)可以衍生多个线程,并在内部为系统提供指令。通过这种方式,如果一个进程是cpu密集型的,那么可以跨内核共享负载,从而有效地使大多数应用程序更快地完成任务。

如果您以前没有做过多线程编程,那么您需要快速熟悉锁的概念。与单线程进程不同,您需要确保在更改内存中的变量时,多个线程不会尝试同时访问/更改相同的内存地址。

当CPython创建变量时,它分配内存,然后计算有多少对该变量的引用存在,这是一个称为引用计数的概念。如果引用的数量为0,那么它将从系统中释放那块内存。这就是为什么在for循环的范围内创建“临时”变量不会增加应用程序的内存消耗。

当变量在多个线程中共享时,挑战就变成了CPython如何锁定引用计数。有一个“全局解释器锁”,它小心地控制线程的执行。解释器一次只能执行一个操作,不管它有多少线程。

那么其他Pythonruntimes呢?

PyPy有一个GIL,它通常比CPython快3倍。

Jython没有GIL,因为Jython中的Python线程由Java线程表示,并且受益于JVM内存管理系统。

JavaScript是如何做到这一点的?

首先,所有Javascript引擎都使用标记-清除垃圾收集。如前所述,GIL的主要需求是CPython的内存管理算法。

JavaScript没有GIL,但它也是单线程的,所以不需要GIL。JavaScript的事件循环和承诺/回调模式是实现异步编程而不是并发的方式。Python对异步事件循环也有类似的处理。

2.因为这是一种解释语言

我经常听到这种说法,我发现这是对CPython实际工作方式的一种粗略简化。如果您在终端上编写了pythonmyscript.py,那么CPython将开始一长串的读取、词法分析、解析、编译、解释和执行这些代码

在这个过程中很重要的一点是创建一个.pyc文件,在编译器阶段,字节码序列被写到Python3上的_pycache__/中的一个文件中,或者在Python2的相同目录中。这不仅适用于您的脚本,还适用于您导入的所有代码,包括第三方模块。

所以大多数时候(除非您编写的代码只运行一次?),Python都是解释字节码并在本地执行它。与Java和c#.NET相比:Java编译成“中间语言”,Java虚拟机读取字节码并及时将其编译成机器码。netCIL是一样的,.net公共语言运行时(CLR)对机器代码使用即时编译。

那么,如果Python都使用虚拟机和某种字节码,那么为什么在基准测试中它比Java和c#慢那么多呢?

首先,.net和Java是jit编译的。JIT或即时编译需要一种中间语言来允许将代码分割成块(或帧)。提前(AOT)编译器的设计是为了确保CPU在进行任何交互之前能够理解代码中的每一行。

JIT本身并没有使执行变得更快,因为它仍然在执行相同的字节码序列。但是,JIT允许在运行时进行优化。一个好的JIT优化器会看到应用程序的哪些部分被频繁地执行,称之为“热点”。然后,它将对这些代码进行优化,用更高效的版本替换它们。

这意味着当您的应用程序一次又一次地做同样的事情时,它可以显著地更快。另外,请记住Java和c#是强类型语言,因此优化器可以对代码进行更多的假设。

PyPy有一个JIT,正如前一节所提到的,它比CPython要快得多。

那么为什么CPython不使用JIT呢?

jit也有缺点:其中之一就是启动时间。CPython的启动时间已经比较慢了,PyPy比CPython慢2-3倍。众所周知,Java虚拟机的启动速度很慢。netCLR通过在系统启动时启动来解决这个问题,但是CLR的开发人员还开发运行CLR的操作系统。

如果您有一个运行了很长时间的Python进程,其中的代码可以进行优化,因为它包含“热点”,那么JIT就很有意义。

然而,CPython是一种通用实现。因此,如果您正在使用Python开发命令行应用程序,那么每次调用CLI时都必须等待JIT启动,这将是非常慢的。

CPython必须尝试并服务尽可能多的用例。在CPython中插入JIT是有可能的,但是这个项目在很大程度上已经停止了。如果您希望获得JIT的好处,并且有适合它的工作负载,那么可以使用PyPy。

3.因为它是动态类型语言

态类型”语言中,必须在声明变量时指定变量的类型。包括C,c++,Java,c#,Go。在动态类型语言中,仍然有类型的概念,但是变量的类型是动态的。

在这个例子中,Python创建了第二个具有相同名称和str类型的变量,并释放为a的第一个实例创建的内存

静态类型语言的设计并不是为了让您的工作变得困难,而是因为CPU的操作方式。如果最终需要将所有操作都等同于简单的二进制操作,则必须将对象和类型转换为低级数据结构。

Python为您做了这些,您只是从来没有见过它,也不需要关心它。

不需要声明类型并不是使Python变慢的原因,Python语言的设计使您能够使几乎任何东西都是动态的。您可以在运行时替换对象上的方法,您可以在运行时对低级系统调用的值进行monkey-patch。几乎一切皆有可能。

正是这种设计使得优化Python变得非常困难。

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

比较和转换类型的成本很高,每次读取、写入或引用某个变量时,都要检查该类型很难优化一门如此动态的语言。Python的许多替代品之所以如此之快,是因为它们在性能的名义下对灵活性做出了妥协看看Cython,它结合了C-Static类型和Python来优化已知类型的代码,可以提供84x的性能改进。结论

Python的主要缺点是它的动态性和通用性。它可以作为解决各种问题的工具,在这些问题中,可能有更优化、更快的替代方案。

但是,可以通过利用异步、理解分析工具和考虑使用多解释器来优化Python应用程序。

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

对于您的代码中性能非常重要并且有更多静态类型变量的部分,可以考虑使用Cython。

以上内容为大家介绍了为什么python这么慢,希望对大家有所帮助,如果想要了解更多Python相关知识,请关注IT培训机构:千锋教育。http://www.mobiletrain.org/

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

pythontime模块的时间格式

2023-11-14

python怎样使用read读取不同类型文件

2023-11-14

python装饰属性的方法

2023-11-14

最新文章NEW

pythonsys模块有哪些用法

2023-11-14

python开发环境是什么

2023-11-14

pythoninsert函数是什么

2023-11-14

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>