Python运行过慢 python运行变慢 您所在的位置:网站首页 python命令行运行py文件无效 Python运行过慢 python运行变慢

Python运行过慢 python运行变慢

2023-06-22 02:29| 来源: 网络整理| 查看: 265

Python运行过慢 python运行变慢_人工智能

众所周知,Python比静态类型的编程语言(如C,C ++,Java和某些动态语言,如JavaScript和PHP)要慢得多。 让我们看一下为什么Python与这些语言相比要慢得多的原因, 以及如何提高其执行速度。

为什么Python变慢?

Python'CPython '的默认实现使用GIL(全局解释器锁定)来同时执行一个线程,即使在多核处理器上运行也是如此,因为GIL仅在一个核上工作,而与内核中存在的核数无关。机。 CPU中的每个内核都有其自己的GIL,因此四核CPU将具有4个GIL,并分别使用其自己的解释器运行。 为了使我们的python程序并行运行,我们使用多线程和多处理。

由于多线程使用相同的内存空间和单个GIL,因此在执行时间上并没有多大差异,因此,由于CPU之间绑定的锁是在线程之间共享的,因此任何与CPU绑定的任务都不会对多线程程序的性能产生影响。在同一个内核中,只有一个线程在等待其他任务完成处理时才执行。 另外,线程使用相同的内存,因此必须采取预防措施,否则两个线程将同时写入同一内存。 这就是为什么需要全局解释器锁定的原因。

由于每个Python进程都有自己的Python解释器和内存空间,因此多处理提高了程序的性能,因此GIL不会成为问题。 但由于多个进程比多个线程重,因此也增加了进程管理的开销。 另外,每次更新一个内存中的对象时,我们都需要将对象从一个内存共享到另一个内存,因为内存彼此之间没有链接,并且分别执行任务。

GIL是引起问题的原因吗? 我们为什么不删除它?

由于即使在具有多个CPU内核的多线程体系结构中,GIL一次仅允许一个线程执行,因此GIL已被誉为Python的“臭名昭著”功能。 因此,这限制了Python程序的执行速度,并且没有充分利用所提供的资源。

那么,为什么不删除GIL? CPython使用引用计数进行内存管理。 这意味着在CPython中创建的对象具有一个引用计数变量,该变量跟踪指向该对象的引用的数量。 当此计数达到零时,将释放对象占用的内存。

如果我们从CPython中删除GIL,则引用计数变量将不再受保护,因为两个线程可能会同时增大或减小其值。 而且,如果发生这种情况,则可能导致从未释放的内存泄漏,或者更糟糕的是,在仍然存在对该对象的引用的情况下,错误地释放了内存。 这可能会导致崩溃或其他Python程序中的“怪异”错误。

同样,已经有一些尝试从CPython中删除GIL,但是单线程计算机的额外开销通常太大。 实际上,即使在多处理器计算机上,由于锁争用,某些情况实际上也会变慢。

GIL有其他替代方法,例如Jython和IronPython ,它们使用其底层VM的线程方法,而不是GIL方法。

得出结论,现在对我们来说,GIL并不是什么大问题,因为具有GIL的Python程序可以设计成使用单独的进程来实现完全并行,因为每个进程都有自己的解释器,而又有自己的GIL。

在Python实现中使用GIL的好处 :

单线程程序的速度提高。 轻松集成通常不是线程安全的C库。 与没有锁的解释器或使用细粒度的锁的解释器相比,具有单个GIL的实现要容易得多。 Python的动态特性会变慢吗?

我们都知道Python是一种动态类型的编程语言,在这种语言中,我们在分配变量时无需指定变量数据类型。 数据类型在运行时分配给变量,因此每次读取,写入或引用变量时,都会检查其数据类型并相应地分配内存 。

静态类型的编程语言相对于此有一个优势,因为数据类型是已知的,因此它们不需要每次在程序中使用变量时都检查数据类型。 因此,这为他们节省了大量时间,并使整个执行过程更快。

Python语言的设计使我们能够使几乎任何东西动态化。 我们可以在运行时替换对象上的方法,我们可以将低级系统调用猴子补丁到运行时声明的值。 几乎所有可能。 因此,不必声明类型并不是让Python变慢的原因,正是这种设计使优化Python 变得异常困难 。

“ CPython在运行时进行解释。” 这是Python程序执行缓慢的问题吗?

一旦我们运行Python程序,就会首先使用CPython(以“ C”编程语言编写)将源代码.py文件编译为保存在__pycache__文件夹(Python 3)中的中间字节码.pyc文件,然后由Python虚拟机进行解释机器代码。

Python运行过慢 python运行变慢_Python_02

由于CPython使用一个解释器 ,该解释器在运行时直接执行生成的字节码,因此,由于在执行程序时解释每一行,因此执行速度大大降低。 而其他编程语言(例如C,C ++)在使用Ahead of time(AOT)编译执行之前直接编译为机器代码。 另外,Java编译为“中间语言”,而Java虚拟机读取字节码,并且即时(JIT)将其编译为机器码。 .NET通用中间语言(CIL)相同, .NET通用语言运行时(CLR)使用即时(JIT)编译来处理机器代码。

我们知道, AOT编译比解释要快,因为该程序在执行任何操作之前已经被编译成机器可读的代码。 但是,JIT编译如何比CPython实现的程序更快地运行程序?

JIT编译是两种转换为机器代码的传统方法的组合- 提前编译(AOT)和解释 -并结合了两者的优点和缺点。 因此,JIT编译通过编译程序中经常使用并在程序运行时与其余代码一起执行的某些部分来优化我们的程序。

某些Python实现(例如PyPy)使用JIT编译,其编译速度比CPython快4倍以上。 那么CPython为什么不使用JIT?

JIT也有缺点,其中之一就是启动时间延迟 。 与CPython相比,使用JIT的实现的启动时间明显慢得多。 CPython是用于开发命令行(CLI)程序和项目的通用实现 ,这些程序和项目不需要太多的CPU工作。 可以在CPython中使用JIT,但由于其难于实施且在Python中缺乏灵活性,因此很大程度上已停滞不前。

“如果您想让代码运行得更快,您可能应该只使用PyPy。” -Guido van Rossum(Python的创建者)

CPython的替代方法是什么?

在流行的Python库(如Django)的支持下, PyPy被认为是Python最快的实现,并且与现有的Python代码高度兼容。 PyPy有一个GIL并使用JIT编译,因此它结合了两者的优点,使整体执行比CPython快得多。 多项研究表明,它比CPython快7.5倍。

PyPy如何工作?

PyPy首先获取我们的Python源代码,并将其转换为RPython ,它是Python的静态类型受限子集。 RPython是一种静态类型的语言,因此更易于编译成更有效的代码。 然后,PyPy 将生成的RPython代码与以“ C”编程语言编写的解释器一起转换为字节码形式。 然后,大部分代码将被编译为机器代码,并且字节码在已编译的解释器上运行。

这是此实现的直观表示:

Python运行过慢 python运行变慢_人工智能_03

它还允许可插入的垃圾收集器 ,以及可选地启用Stackless Python功能。 最后,它包括一个即时(JIT)生成器 ,它在解释器源代码中给出了一些注释,从而将即时编译器构建到解释器中。 生成的JIT编译器是跟踪JIT 。

这是对实现方式的简要说明,如果您想了解有关PyPy的更多信息,那么可以在此处阅读更多内容。

为什么我们不使用PyPy作为Python中的标准实现?

当我们讨论JIT的缺点是启动时间延迟时,PyPy遵循了该套件。 而且,PyPy 与许多C扩展都不兼容,因为CPython是用“ C”编程语言编写的,而PyPI上的第三方扩展利用了这一优势。 Numpy就是一个很好的例子,Numpy的大部分内容都是用优化的C代码编写的。 当我们pip install numpy ,它将使用我们的本地C编译器并为我们的Python运行时建立一个二进制库供使用。

PyPy是用Python编写的,因此我们需要确保在项目中实现PyPy支持项目所需的模块。

这就是为什么不使用PyPy作为Python中的默认实现的原因。 除了PyPy外,还有许多其他可用于Python的实现,可以替代使用这些实现以使Python运行更快,因此您可以选择最适合自己的一种。

结论

我提出的发现表明,与其他静态类型的语言(例如C,C ++,Java)相比,Python的动态特性确实是一种慢速语言。 但是,我们应该在乎吗?

可能不是,因为我们都知道在我们的项目中使用Python可以节省多少开发时间。 初创企业已经在其项目中广泛使用Python,以便尽快将其产品推向市场。 这样可以为他们节省大量人工成本和单个产品上的工时 。 诸如Django之类的框架通过已提供的许多基本功能,已使全栈开发成为可能。

如果在整体上进行机器学习,大数据和人工智能工作时性能受到限制,则Python开发人员正在为Python采用最佳实现 。 当使用现代和动态语言时,可能性是无止境的,而如今,它在Python Package Index(PyPI)中提供了100,000多个库的广泛支持。 这样一来,开发人员可以同时轻松,快速地工作。

进一步阅读

如果您想了解有关Python GIL,Python实现,Python字节码以及它们如何工作的更多信息,我建议以下资源:

您可以从Python Wiki页面上查看有关Python实现的更多信息,以获取各种可用的Python实现。 如果您想知道Python字节码是如何工作的,那么这是我到目前为止发现的最佳资源。 另外,请查看David Beazley关于理解Python GIL 2012视频版本的演讲。 您也可以查看以前的2009 PDF版本的David Beazley关于GIL的演讲。 如果您想了解有关PyPy的更多信息,那么可以开始使用本PyPy文档 。


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有