程序员应知应会之Python为什么性能比较差?精选

  • 信息时代风之影
  • 2023/5/6 15:06:20
随着深度学习的火热,作为深度学习重要编程工具的Python也越来越多的受到了人们的青睐。

       随着深度学习的火热,作为深度学习重要编程工具的Python也越来越多的受到了人们的青睐。当然,有些人认为这是因为相比于其它编程语言来说,Python之父吉多·范罗苏姆的发量明显要多,所以这也是很多程序员选择Python作为自己的主要编程语言的原因。其实细究起来,这种说法也可能有一定道理,因为从一开始,Python作为一种编程语言,其主要目的就是为了减少程序员的工作量,而让大量的工作由电脑来完成。而这也是吉多·范罗苏姆发明Python的初衷:”life is short,we use python。”因此,节省了很多工作量的Python开发者,头发相比其它程序员来说多一点也是可以理解的。

       但是开发效率提高了之后,不可避免地带来了程序运行效率低下的问题。从测试情况来看,同样的算法,Python的运行效率比C++要慢几倍,甚至几十倍。

那么为什么Python的效率要低这么多呢?原因主要是以下几点:

一、Python是动态语言

       很多程序员都知道,Python是一门动态(dynamic)且强类型(strong)的语言。所谓动态语言,意味着类型检查发生在运行时,而不是编译时,在Python中,类型并不需要被显式声明,而是在运行阶段才会被赋值。

       因为变量所指向的类型在运行时才会被确定,编译器就做不了任何的预测,所以也就没法进行优化。即使是最简单的加法,针对不同类型也有不同的处理方式,而Python因为不能提前预知数据的类型,所以只有等到运行时,才会根据对应的数据类型选择相应的操作,而不是事先准备好,这样就造成了效率的低下。

二、Python中的假多线程处理

       尽管Python支持基于线程的并发编程,但是实际上,由于全局解释锁(Global Interpreter Lock, GIL)的存在,使得任意指定时刻,只有单个Python线程能够执行,无论系统上存在多少可用的GPU核心。

       GIL一次只允许一个线程执行,每执行100条字节码,解释器就会释放GIL锁,让别的线程有机会执行,所以Python的多线程只能交替执行,这大大影响了执行效率。

三、Python中一切皆为对象

       在Python中,”一切皆为对象”是一种重要的概念。这意味着,Python中的每个元素——包括数字、字符串、数据结构、函数、模块等等——都被视为一个对象,包含了数据和行为。数据可以是各种类型的值,行为则是对象可以执行的动作或操作。在Python中,每个对象都有一个类型,这个类型定义了对象能够执行哪些操作和支持哪些方法。 在Python中,所有类都继承自一个名为object的基类。

       而简单的数据也是一个对象的设计理念,加重了Python的垃圾回收负担。在Python中,使用计数器记录了每个对象的引用,当这个对象的引用计数变为0 时, 它被垃圾回收。但是回收不是"立即"的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。

       垃圾回收机制不仅针对引用计数为0的对象,同样也可以处理循环引用的情况。循环引用指的是,两个对象相互引用,但是没有其他变量引用他们。这种情况下,仅使用引用计数是不够的。Python 的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。作为引用计数的补充,垃圾收集器也会留心被分配的总量很大(即未通过引用计数销毁的那些)的对象。在这种情况下,解释器会暂停下来,试图清理所有未引用的循环。

       这种基于对象计数器的垃圾回收机制,极大地影响了Python程序运行的效率。

       正因为这些设计理念书的存在,导致Python的运行效率相比于其它编程语言来说较为低下。之前Google曾经启动了一个旨在优化Python执行效率的unladen-swallow项目,该项目计划将Python的执行效率提高5倍,但是收效甚微,于是Google不得不停止了这种不切实际的幻想。

       但是对于程序员来讲,能够提高编程效率就好了,至于服务器多跑几个小时,反正也累不着嘛,还促进了用电消费,一举多得,岂不美哉。

责任编辑:水告    来源:活在信息时代

相似话题