PyPy 为什么会比 CPython 还要快?

转载 2018年04月16日 23:21:40
你本来有个 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 和 Unladen Swallow 对比的话,最大的不同点就是前者基本完工了(可用),后者做一半坑了。另外的区别的话,Unladen Swallow 立项的目的是完全兼容 CPython,于是直接再 CPython 的 codebase 上改,想要把之前 CPython 解释执行的部分改成 JIT 执行,然后内存模型不改,于是就能兼容 Cpython(包括原生扩展)。Pypy 的话基本都是自己重写的,(原生扩展)兼容性没有放在第一位了。

其实你还不懂Word

-
  • 1970年01月01日 08:00

Python, CPython, Pypy, Jython的简单介绍

简单地说,Python是一门编程语言,任何一种编程语言都需要用另一种语言来实现它,比如C语言就是用机器语言来实现的。所以,Python根据实现方式不同分为了CPyhton、Pypy、Jython等。C...
  • red_stone1
  • red_stone1
  • 2017-05-03 17:48:51
  • 2578

PyPy和CPython的不同点

http://pypy.readthedocs.io/en/latest/cpython_differences.html 挖个坑,有时间再看。
  • qq_33528613
  • qq_33528613
  • 2017-06-03 21:16:06
  • 592

PyPy 和 CPython 的性能比较测试

最近我在维基百科上完成了一些数据挖掘方面的任务。它由这些部分组成: 解析enwiki-pages-articles.xml的维基百科转储; 把类别和页存储到MongoDB里面; 对类...
  • langsim
  • langsim
  • 2015-03-17 18:14:39
  • 1673

pypy确实要比我们平时用的python快

什么是pypypypy就是用python实现的python。 我们平时用的python,一般叫Cpython,是由C语言开发的python。 pypy的速度反而要快于我们现在使用的Cpython。...
  • yyw794
  • yyw794
  • 2017-06-25 23:26:19
  • 315

Python的各种解释器实现CPython | PyPy | Jython | IronPython等

Python解释器或Python虚拟机有很多种实现,有CPython、PyPy、Jython以及IronPython等。CPython是最主流的实现。CPython同时也是别的虚拟机实现的参考解释器。...
  • wangjianno2
  • wangjianno2
  • 2016-08-20 23:09:24
  • 1385

为什么get比post更快

引言   get和post在面试过程中一般都会问到,一般的区别:   1.post更安全(不会作为url的一部分,不会被缓存、保存在服务器日志、以及浏览器浏览记录中)   2.pos...
  • kkopopo
  • kkopopo
  • 2014-03-26 22:37:45
  • 411

Pyston与PyPy:为Python提速的两种不同方式

 让Python又快速又稳定的方法是什么?这个问题的答案,取决于你问的是谁。 如果是迅速成长的Pyston项目的创始人Dropbox,那么选择将会是从目前的Python着手,优化它的速度。如果...
  • dj0379
  • dj0379
  • 2016-07-18 23:14:12
  • 3695

Pypy Python的JIT实现

转自:https://www.cnblogs.com/hitfire/articles/4502199.html Pypy从表面意思上面来说的话,就是用Python实现的Python...
  • bluehawksky
  • bluehawksky
  • 2018-01-05 18:45:00
  • 256

Producer

public class Producer { private static String url = ActiveMQConnection.DEFAULT_BROKER_URL; ...
  • jiangxuchen
  • jiangxuchen
  • 2012-09-21 16:23:44
  • 758
收藏助手
不良信息举报
您举报文章:PyPy 为什么会比 CPython 还要快?
举报原因:
原因补充:

(最多只允许输入30个字)