🐢python慢的原因
前言
相比C/C++/JAVA, Python确实慢,在一些特殊场景下,Python比C++慢100~200倍由于速度慢的原因,很多公司的基础架构代码依然用C/C++开发比如各大公司阿里/腾讯/快手的推荐引擎\搜索引擎、存储引擎等底层对性能要求高的模块。
原因
-
是动态类型语言,变解释变运行:
- C与C++运行的时候要先进行编译,编译成为可以直接生成运行效率高的机械码,可以看到每次运行都生成了.exe
- python执行的时候是源码,需要一个源码到机械码的过程。
-
变量:
- 变量随时切换,所以运行的时候要随时检查类型。
-
GIL(Global Interpreter Lock)
- 导致python无法多核CPU并发执行
GIL
全局解释器锁(英语:Global Interpreter Lock,缩写GIL)
是计算机程序设计语言解释器用于同步线程的一种机制,它使得任何时刻仅有一个线程在执行。即便在多核心处理器上,使用GIL的解释器只允许单个时刻单个进程只能使用一个线程。
(java的多线程,如果是在单核cpu上,实际上也是同时只有一个线程执行,只是多线程之间进行快速切换,感觉像是多线程一样)
为什么要引入GIL
简而言之:Python设计初期,为了规避并发问题引入了GIL,现在想去除却去不掉了!
为了解决多线程之间数据完整性和状态同步问题,Python中对象的管理,是使用引用计数器
进行的。就是通过一个变量被引用的次数来判断是否需要被释放。引用数为0则释放对象。
如下图:线程A和线程B都引用了对象obj,则obj.ref_num=2,而这个时候线程A和B都正好撤销对obj的引用:
- A:obj.ref_num=1
- B:obj.ref_num=0,B中撤销obj
- A:A要撤销的时候发现,没有obj了,报错。严重会撤销其他的内存参数。
所以引入GIL简化了python对共享资源的管理。
(java有垃圾回收器,和标记清除算法等,对象的回收由垃圾回收器来解决)
规避GIL带来的限制
- 多线程threading 机制依然是有用的,用于IO密集型计算因为在I/O (read,write,send,recv,etc.)期间,线程会释放GIL,实现CPU和IO的并行因此多线程用于IO密集型计算依然可以大幅提升速度但是多线程用于CPU密集型计算时,只会更加拖慢速度
- Python提供了multiprocessing,使用multiprocessing 的多进程机制实现并行计算、利用多核CPU优势为了应对GIL的问题。
(Python由于cpython解释器的原因,似乎=对多进程并不支持,但是可以通过multiprocessing调用多个解释器来实现多进程。)
thon解释器的原因,似乎=对多进程并不支持,但是可以通过multiprocessing调用多个解释器来实现多进程。)