什么阻止Ruby,Python来获得Javascript V8的速度?
有没有任何Ruby / Pythonfunction阻止优化的实现(例如内联caching )V8引擎?
Python由Google合作开发,所以不应该被软件专利所阻挡。
或者这是Google投入V8项目的资源问题。
什么阻止Ruby,Python来获得Javascript V8的速度?
没有。
那么,好吧:钱。 (时间,人,资源,但如果你有钱,你可以买这些。)
V8拥有一支精干,高度专业化,经验丰富(因而薪水高)的工程师队伍,拥有数十年的经验(我个人正在谈论 – 几乎是几个世纪以来)创造高性能的执行用于dynamicOO语言的引擎。 他们基本上是同样创build了Sun HotSpot JVM的人(等等)。
首席开发人员Lars Bak已经从事虚拟机工作了25年(所有这些虚拟机已经领导到V8),这基本上是他整个(专业)的生活。 一些编写Ruby虚拟机的人甚至不到25岁。
有没有任何Ruby / Pythonfunction阻止优化的实现(例如内联caching)V8引擎?
鉴于至lessIronRuby,JRuby,MagLev,MacRuby和Rubinius有单态(IronRuby)或多态内联caching,答案显然不是。
现代的Ruby实现已经做了大量的优化。 例如,对于某些操作,Rubinius的Hash
类比YARV更快。 现在,直到你意识到Rubinius的Hash
类在100%纯Ruby中被实现,而YARV被实现在100%手工优化的C中,这听起来并不令人兴奋。
所以,至less在某些情况下,Rubinius可以比GCC生成更好的代码!
或者这是Google投入V8项目的资源问题。
是。 不只是Google。 V8的源代码现在已经25年了。 在V8上工作的人也创build了Self VM(到目前为止创build的最快的dynamicOO语言执行引擎之一),Anomorphic Smalltalk VM(迄今为止创build的最快的Smalltalk执行引擎之一),HotSpot JVM(曾经创build的最快的JVM,可能是最快的VM周期)和OOVM(创build的最有效的Smalltalk VM之一)。
事实上,V8的首席开发人员Lars Bak曾为其中的每一个人员,以及其他一些人员工作。
高度优化JavaScript解释器有更多的动力,这就是为什么我们看到Mozilla,Google和Microsoft之间投入了如此多的资源。 JavaScript必须被实时下载,parsing,编译和运行,而一个(通常是不耐烦的)人在等待它,它必须在一个人正在与之交互时运行,而且这是在一个不受控制的客户端环境可以是电脑,电话或烤面包机。 为了有效地在这些条件下运行,它必须是有效率的。
Python和Ruby运行在由开发者/部署者控制的环境中。 一个健壮的服务器或桌面系统通常在限制因素将是内存或磁盘I / O,而不是执行时间的东西。 或者可以使用像caching这样的非引擎优化。 对于这些语言来说,将重点放在语言和库特性设置上来优化速度可能更有意义。
这样做的好处是,我们有两个伟大的高性能开源JavaScript引擎,可以和正在重新使用各种应用程序,如Node.js。
其中很大一部分与社区有关。 Python和Ruby大部分没有企业支持。 没有人能够得到报酬来全职工作在Python和Ruby上(特别是他们没有得到报酬一直在CPython或MRI上工作)。 另一方面,V8则得到了世界上最强大的IT公司的支持。
此外,V8可以更快,因为对于V8人来说唯一的事情就是翻译 – 他们没有标准的图书馆可以工作,不用担心语言devise。 他们只是写翻译。 而已。
这与知识产权法无关。 Google合作伙伴也不是Python合作开发的(它的创build者和其他一些提交者一起工作,但是他们没有从Python获得报酬)。
Python速度的另一个障碍是Python 3.它的采用似乎是语言开发人员的主要关注点 – 直到其他实现迎头赶上,才冻结了新语言function的开发。
在技术细节方面,我对Ruby不是很了解,但是Python有很多可以使用优化的地方(而Google的项目Unladen Swallow在开始实施之前就已经开始实施了)。 以下是他们计划的一些优化 。 如果JIT a la PyPy被实现为CPython,我可以看到Python在未来获得了V8的速度,但是在未来几年似乎不太可能(现在的重点是Python 3的采用,而不是JIT)。
许多人也认为,Ruby和Python可以从删除他们各自的全局解释器锁中受益匪浅。
您还必须明白,Python和Ruby比JS更重的语言 – 他们提供了更多的标准库,语言function和结构的方式。 仅仅面向对象的类系统就会增加很多的重量(我认为是一个很好的方法)。 我几乎把Javascript看作一种被embedded的语言,就像Lua(在很多方面它们是相似的)。 Ruby和Python有更丰富的特性,而且expression性通常是以速度为代价的。
性能似乎不是核心Python开发人员的主要焦点,他们似乎认为“足够快”足够好,而且帮助程序员提高生产力的function比帮助计算机更快运行代码的function更重要。
然而,事实上,现在有一个(现在已经被放弃的)Google项目,可以生产一个与标准解释器兼容的更快的Python解释器。 PyPy是另一个计划,旨在生产更快的Python。 还有Psyco ,PyPy的前身,它可以在不改变整个解释器的情况下为许多Python脚本提供性能提升, Cython可以使用非常像Python语法的东西为Python编写高性能C库。
误导性的问题。 V8是JavaScript的一个JIT(即时编译器)实现,在其最stream行的非浏览器实现Node.js中,它是围绕事件循环构build的。 CPython不是一个JIT&没有完成。 但是这些在PyPy项目中最常见的Python存在 – 一个CPython 2.7(不久将是3.0+)兼容的JIT。 例如,有一些像Tornado这样的服务器库。 运行Tornado和Node.js的PyPy之间存在真实世界的testing,性能差异很小。
我只是遇到了这个问题,这也是没有提到的性能差异的一个重大技术原因。 Python有一个非常大的强大的软件扩展生态系统,但是这些扩展中的大多数都是用C或其他低级语言编写的,因此性能非常强大,并且与CPython API息息相关。
有很多众所周知的技术(JIT,现代垃圾收集器等)可以用来加速CPython的实现,但都需要对API进行重大更改,从而破坏了过程中的大部分扩展。 CPython会更快,但是很多让Python如此吸引人的东西(广泛的软件堆栈)将会丢失。 举个例子来说,有几个更快的Python实现,但与CPython相比,它们几乎没有牵引力。
由于不同的devise优先级和用例目标,我相信。
一般来说,脚本(又名dynamic)语言的主要目的是成为本地函数调用之间的“粘合剂”。 这些原生function应:a)覆盖大部分关键/经常使用的区域; b)尽可能有效。
下面是一个例子: jQuerysorting导致iOS Safari冻结由于过度使用get-by-selector调用而导致的冻结。 如果get-by-selector将在本地代码中实现,并且实际上不会有这样的问题。
考虑经常使用V8演示的演示的光线跟踪器演示。 在Python世界中,它可以用本地代码实现,因为Python为本机扩展提供了所有的function。 但是在V8领域(客户端沙箱)中,除了使虚拟机尽可能有效之外,没有别的select。 所以唯一的select是通过使用脚本代码来看到ray-tracer的实现。
所以不同的优先事项和动机。
在Sciter中,我通过本地实现了几乎完整的jQurey核心进行了testing。 在像ScIDE (由HTML / CSS / Script构成的IDE)这样的实际任务上,我认为这样的解决scheme比任何虚拟机优化都更有效。
正如其他人所提到的,Python具有PyPyforms的高性能JIT编译器。
制定有意义的基准总是微妙的,但是我碰巧有一个用不同语言编写的K-means的简单基准 – 你可以在这里find它。 其中一个约束就是各种语言都应该实现相同的algorithm,并且应该努力做到简单和习惯(与速度优化相反)。 我已经写了所有的实现,所以我知道我没有欺骗,虽然我不能要求所有的语言,我写的是惯用的(我只有一些这些传递知识)。
我没有要求任何明确的结论,但PyPy是我得到的最快的实现之一,远胜于Node。 相反,CPython处于排名的最低端。
声明不完全正确
就像V8只是JS的实现一样,CPython只是Python的一个实现。 Pypy的performance与V8相匹配 。
此外,还有性能问题:由于V8本身是非阻塞的,所以Web dev会导致性能更高的项目,因为您可以节省IO等待时间。 而V8主要用于IO关键的开发Web,因此将它与类似的项目进行比较。 但是,除了web开发之外,还可以在许多其他领域使用Python。 甚至可以使用C扩展来完成许多任务,比如科学计算或者encryption,并且可以通过眩目的perf来压缩数据。
但是在networking上,大多数stream行的Python和Ruby项目都是阻塞的。 特别是,Python具有同步WSGI标准的遗产,像着名的Django这样的框架就是基于它的。
你可以编写asynchronousPython(比如Twisted,Tornado,gevent或者asyncio)或者Ruby。 但这并不经常。 最好的工具仍然阻塞。
然而,他们是为什么Ruby和Python中的默认实现不如V8那么快的原因。
经验
就像JörgW Mittag指出的那样,从事V8工作的人是VM天才。 Python是一群热情的人开发的,在很多领域都非常擅长,但是并不是专门针对VM调优的。
资源
Python软件基金会的资金非常less:每年投入Python 不到4万美元。 当你认为谷歌,Facebook或者苹果这样的大玩家都在使用Python的时候,这有点疯狂,但是这是一个丑陋的事实:大部分的工作都是免费的。 在Java之前,这个语言就是由志愿者手工制作的。
他们是聪明和忠诚的志愿者,但是当他们发现他们需要更多的果汁时,他们不能要求30万人才能聘请这方面的顶尖专家。 他们必须四处寻找一个免费的人。
虽然这有效,但这意味着你必须非常小心你的优先事项。 因此,现在我们需要看看:
目标
即使有最新的现代function,写Javascript是可怕的。 你有范围问题,很less的集合,可怕的string和数组操作,除了date,math和正则expression式几乎没有stdlist,即使是非常常见的操作也没有语法糖。
但在V8中,你有速度。
这是因为速度是Google的主要目标,因为它是Chrome中页面呈现的瓶颈。
在Python中,可用性是主要目标。 因为它几乎从来不是项目的瓶颈。 这里稀缺的资源是开发者的时间。 它是为开发人员优化的。
因为JavaScript实现不需要关心绑定的向后兼容性。
直到最近,JavaScript实现的唯一用户已经是Web浏览器。 由于安全要求,只有networking浏览器供应商才有权通过编写绑定到运行时来扩展function。 因此,不需要保持绑定的C API向后兼容,允许Web浏览器开发者在JavaScript运行时发展时更新其源代码; 他们正在一起工作。 即使V8也是这个游戏的后来者,也是由一位非常有经验的开发人员领导的,它已经改变了API,因为它变得更好。
OTOH Ruby(主要)在服务器端使用。 许多stream行的ruby扩展都被写成C绑定(考虑一个RDBMS驱动)。 换句话说,如果不维护兼容性,Ruby将永远不会成功。
今天,差距还是有的。 使用node.js的开发人员抱怨说,由于V8会随着时间的推移而改变API(这是node.js被分叉的原因之一),所以很难保持它们的本地扩展向后兼容。 IIRCruby在这方面仍然采取更保守的方法。
由于JIT,曲轴,types推理器和数据优化代码,V8是快速的。 标记的指针,双打的NaN标记。 当然,它在中间正常的编译器优化。
普通的ruby,python和perl引擎都不做这些,只是一些小的基本优化。
接近的唯一的主要是luajit,它甚至不进行types推断,不断的折叠,NaN标记或整数,而是使用类似的小代码和数据结构,而不是像坏语言一样胖。 我的原型dynamic语言potion和p2与luajit有相似的function,并且胜过v8。 使用可选的types系统“渐进式打字”,您可以轻松超越v8,因为您可以绕过曲轴。 看飞镖。
已知的优化后端,如pypy或jruby仍然受到各种过度工程技术。