PyPy的原理是什么

这篇文章主要讲解了“PyPy的原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PyPy的原理是什么”吧!

项目背景

PyPy 是 Python 开发者为了更好地 Hack Python 创建的项目。此外,PyPy 比 CPython 更灵活,易于使用和试验,以制定具体的功能在不同情况的实现方法,可以很容易实施。该项目的目标是,让 PyPy 比 C 实现的 Python 更为容易地适应各个项目和方便裁剪。 

项目现状

PyPy 是 Armin Rigo 开发的,Python 语言的动态编译器,是 Psyco 的后继项目。PyPy 的目的是,做到 Psyco 没有做到的动态编译。

PyPy 开始只是研究性质的项目。但是开发非常成熟,在 2007 年中旬发布了 1.0 Release 版本后,大家关注的焦点是,能否在 2008 年出现可供生产环境使用的版本。

它支持 Python 语言的所有核心部分以及大多数的 Python 语言标准库函数模块,并且通过了 Python 语言的 test suite。与 CPython 的区别可以去看它的兼容性页面.

PyPy 还提供了 JIT 编译器和沙盒功能,因此运行速度比 CPython 要快,以及可以安全地运行一些不被信任的代码。PyPy 还有一个单独的支持微线程的版本。

另外,PyPy 也有每夜构建版本供开发者测试。

PyPy 是作为 Specific Targeted Research Projects(特定领域研究项目)从 2004 年 12 月到 2007 年 3 月,开始接受欧盟的援助。

 

PyPy 的原理

我们通过一个例子与 Python 执行过程对比来看PyPy 的原理[2]

你本来有个 python 代码:

def add(x, y):
   return x + y

 

然后 CPython 执行起来大概是这样(伪代码):

if instance_has_method(x, '__add__') {
   return call(x, '__add__', y) // x.__add__ 里面又有一大堆针对不同类型的 y 的判断
} else if isinstance_has_method(super_class(x), '__add__' {
   return call(super_class, '__add__', y)
} else if isinstance(x, str) and isinstance(y, str) {
   return concat_str(x, y)
} else if isinstance(x, float) and isinstance(y, float) {
   return add_float(x, y)
} else if isinstance(x, int) and isinstance(y, int) {
   return add_int(x, y)
} else ...

 

这下能看出来因为 Python 的动态类型,一个简单的函数里面要有这么多判断才能正确执行。然后这还没完,你以为里面把两个整数相加的函数,就是 C 语言里面的 x + y 么?naive。实际上 Python 里面一个 int 大概是个这样的结构体(也是伪代码,真实情况要比这个复杂):

struct {
   prev_gc_obj *obj
   next_gc_obj *obj
   type int
   value int
   ... other fields
}

 

然后每个 int 都是这样的结构体,还是动态分配出来放在 heap 上的,里面的 value 还不能变,也就是说你算 1000 这个结构体加 2000 这个结构体,得出来 3000 这个结构体,还要去 heap 上 malloc 一个结构体来。CPython 每次就这么老老实实的执行这个过程,就算你每次调用 add 函数都是只传两个整数。然后 pypy 执行的时候,发现执行了一百遍 add 函数,发现你 TM 每次都只传两个整数进来,那我何苦每次还给你做这么多计算,于是当场生成了一个类似 C 的函数:

int add_int_int(int x, int y) {
 return x + y;
}

然后当场编译成机器码,然后你下次每次调用 add(1, 2) 的时候,直接就调用这个 “Native” 的函数,你说你 Pypy 快不快?上面这个过程就叫做 Just In Time 编译,也就是 JIT,肯定比 CPython 的执行速度要快了。当然 JIT 也有很多问题,比如编译本身也很花时间,如果这段代码本来就只执行一次,需要 1s,但是你把它编译出来需要 10s,那 JIT 就得不偿失了。所以很多 JIT 实现都会先解释执行,然后确定了一段代码经常被执行之后,再进行编译。并且分多层 JIT,比较初级的对编译出来的机器码不做比较复杂的优化什么的。

感谢各位的阅读,以上就是“PyPy的原理是什么”的内容了,经过本文的学习后,相信大家对PyPy的原理是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

原创文章,作者:3628473679,如若转载,请注明出处:https://blog.ytso.com/tech/opensource/219854.html

(0)
上一篇 2022年1月2日 13:46
下一篇 2022年1月2日 13:46

相关推荐

发表回复

登录后才能评论