未编译python代码比go慢100倍-金马国际

        2019 年 12 月 06 日

        我是编译型编程语言的忠实粉丝,一直都是。虽然解释型编程语言可以让开发者更快地编写和测试代码,但我仍然认为是值得长期投入的。在我看来,编译型代码有两个明显的优势:


        • 每次修改代码都可以得到验证,甚至是在开始运行代码之前。

        • 更快的执行速度。根据具体情况,代码可能被编译成非常底层的运行指令。


        我之所以要写这篇文章,是想比较一下编译型代码的执行速度会比解释型快多少。


        因为我偏爱编译型编程语言,所以现在有个问题:我手头有很多感兴趣的代码,但它们都是用 python 写的,我该怎么办?全部重写?部分重写?完全不重写?


        先入之见


        在这篇文章里,我通过比较 、 和 在处理不同任务时的性能表现来验证我对它们的一些先入之见。首先是 python,我正在考虑要不要把它替换掉。至于 java,我已经是 20 多年的粉丝了,一路看着它成熟,不管是性能还是功能都在变得更好。最后是 go,我两年前才开始用它,但真的很喜欢它。虽然 go 相比 java 还缺失了一些特性,比如类继承,但它的语法简洁而紧凑,编译和执行速度都很快,生成的代码也很紧凑,还提供了优雅的 goroutine 来实现并发处理。


        以下是我的一些先入之见。


        • 编译型代码的执行速度比解释型代码要快一个数量级。之前,我比较了使用 jit 和不使用 jit 编译 java 代码所获得的性能,它们的比率大概是 30 比 1。

        • go 的运行速度比 java 要快一点。我记得在之前的工作中做过一些测试,发现 go 在处理某些任务时要比 java 快 30%,但最近一些文章又说 java 比 go 快。


        先来测试一把我在之前的一篇文章中通过一些代码比较过 jit 的性能,后来使用 python 和 go 也实现了一遍。这段代码计算 100 的 fibonacci 数值,每一轮计算 50 次,并打印执行时间(纳秒),共计算 200 轮。代码可以在上找到。


        三种语言的输出结果看起来像这样:


        java   go    python...122    123   11683119    107   11539123    104   11358120    115   11926119    118   11973120    104   11377109    103   12960127    122   15683112    106   11482...
        复制代码


        平均值是这样:


        java   go    python130    105   10050
        复制代码


        可以看到,在计算 fibonacci 数值时,java 比 go 要慢一些,大概慢 24%,而 python 几乎慢了 100 倍,也就是 9458%。


        这个结果验证了我最初对 java 和 go 的判断,但让我感到吃惊的是 python 的表现,它慢得不只是一个数量级,是两个!


        我在想 python 为什么会花这么多时间。


        我首先想到的是,很多人关注的是 python 的易用性,并通过牺牲性能来快速获得处理结果。我相信数据科学家们都是这么想的。况且有这么多现成的库可以用,为什么要去找其他的?迟早会有人优化它们的。


        第二个原因是很多人没有比较过不同的实现,因为很多初创公司在激烈的竞争中忙于做出产品,根本无暇顾及什么优化不优化。


        第三个原因,有一些方式可以让同样的 python 代码跑得更快。


        把 python 代码编译一下会如何


        在做了一些调研之后,我决定使用 pypy 测试一下相同的 python 代码。pypy 是 python 的另一个实现,它本身就是使用 python 开发的,包含了一个像 java 那样的 jit 编译器。跟 java 一样,我们需要忽略初始的输出,并跳过 jit 编译过程,得到的结果如下:


        java   go    python    pypy130    105   10050     1887
        复制代码


        pypy 的平均响应速度比 python 快 5 倍,但仍然比 go 慢 20 倍。


        更多的测试


        以上的测试主要集中在数值的计算上,如果回到最开始所说的 python 代码,我还需要关注:


        • kafka、http 监听器和数据库的 io;

        • 解析 json 消息。


        总结


        本文通过执行简单的数学运算得出这样的结论:go 的执行速度比 java 快一些,比解释运行的 python 快 2 个数量级。


        基于这样的结果,我个人是不会使用 go 来替换 java 的。


        另一方面,在高负载的关键任务上使用 python 不是一个好的选择。如果你正面临这种情况,可以考虑使用 python 编译器作为短期的应急方案。


        在决定是否要重写 python 代码时,还需要考虑到其他因素,比如 io 和 cpu 方面的问题,但这些超出本文的范围了。


        有人提醒我,使用 go 和 java 的 64 位整型只能准确计算出 92 的 fibonacci 数值,再往后会出现溢出(译者:所以代码后来改成了计算 90 的 fibonacci 数值)。但即使是这样,本文的结论仍然是有效的。


        英文原文




        2019 年 12 月 06 日 14:3116510
        infoq 主编

        发布了 395 篇内容, 共 306.9 次阅读, 收获喜欢 1709 次。

        关注

        评论 3 条评论

        发布
        这个话题在python,建立之初一直都有人进行评论。但是,python还是在它擅长的领域,发挥重要作用,这篇文章,就像用 c 的执行效率,和汇编编写的程序进行性能比较,一点意思都没有
        2019 年 12 月 23 日 15:59
        回复
        这么简单的比较性能有何意义?
        numba了解下?
        2019 年 12 月 18 日 12:02
        回复
        java 和 go 是解决不同的问题的
        2019 年 12 月 17 日 16:36
        回复
        没有更多评论了
        • 今天我们一起学习下luajit 中唯一的数据结构:table。

          2019 年 6 月 19 日

        • 想要真正熟练地掌握python或者是任何一门其他的编程语言,拥有大中型产品的开发经验是必不可少的。

          2019 年 5 月 10 日

        • macruby紧随jruby和ironruby,在实验分支中将ruby 1.9的全局解释锁(gil)移除。

        • 这是《死磕java并发编程》系列的第7篇文章 我们在一起来看看 读写锁 reentrantreadwritelock 的源码分析,基于java8。

          2020 年 5 月 2 日

        • 今天我就来解谜,带你一起来看gil。

          2019 年 7 月 1 日

        • “java 微服务能像 go 一样快吗?”为此,我们创建了一系列微服务并进行了基准测试,本文将和大家分享我们的测试结果。

        • 简谈python中的str、byte以及unicode

        • python 作为一种编程语言正在消亡吗?也许有一点,但也只是一点。

        • graalvm是一个高性能的、支持多种编程语言的执行环境。

          2018 年 10 月 8 日

        • travis jensen比较了groovy、jython和jruby在开发web用户界面方面的优劣。

        • 在大数据领域内,每一毫秒的性能损失都影响巨大。然而,像python这样通常被认为性能不是太好的编程语言,在过去一年中却变得越来越流行了。大数据社区最近出现的一些文章和讨论,又一次点燃了用于数据科学以及大数据领域的编程语言选择之争。

        • python 3.0(又名python 3000)在三个月之前终于发布(2008年12月3日)。自python之父guido van rossum开始展望这个全新的、革命性的python版本,已经过去了近9年光景。python 3.0打破了与旧有版本的向后兼容性。

        • python 中有没有办法通过类方法找到其所属的类?

          2020 年 9 月 5 日

        • 不积跬步,无以至千里

          2020 年 5 月 24 日

        • 一个合格的程序员应该掌握几门语言,不仅会让你对不同的语言进行比较,让你有更多的思考,而且也是一种学习能力的培养。

          2018 年 6 月 12 日

        • 2019 年 5 月 15 日

        • effctive java item4

          2020 年 10 月 11 日

        发现更多内容
        网站地图