Answers:
是什么阻碍了Ruby,Python获得Javascript V8速度?
没有。
好吧,好的:钱。(还有时间,人员,资源,但是如果您有钱,就可以购买。)
V8拥有一支由精明,高度专业,经验丰富(因此薪资很高)的工程师组成的团队,他们在创建高性能执行方面拥有数十年的经验(我个人是在讲话,而集体而言更像是几个世纪)动态OO语言的引擎。他们基本上都是创建Sun HotSpot JVM的人(还有许多其他人)。
首席开发人员Lars Bak实际上从事VM已有25年的历史(并且所有这些VM都达到了V8版本),这基本上就是他的整个(职业)生涯。有些编写Ruby VM的人甚至不到25岁。
是否有任何Ruby / Python功能阻止V8引擎执行优化(例如,内联缓存)?
至少考虑到IronRuby,JRuby,MagLev,MacRuby和Rubinius具有单态(IronRuby)或多态内联缓存,答案显然不是。
现代Ruby实现已经进行了大量优化。例如,对于某些操作,Rubinius的Hash
类比YARV的类要快。现在,这听起来并不令人兴奋,直到您意识到Rubinius的Hash
类是在100%纯Ruby中实现的,而YARV的类是在100%手动优化的C中实现的。
因此,至少在某些情况下,Rubinius可以生成比GCC更好的代码!
还是这与Google投入V8项目的资源有关。
是。不只是谷歌。V8的源代码沿袭至今已有25年的历史了。使用V8的人还创建了Self VM(迄今为止,这是迄今为止创建的最快的动态OO语言执行引擎之一),Animorphic Smalltalk VM(迄今为止,是迄今为止创建的最快的Smalltalk执行引擎之一),HotSpot JVM(有史以来最快的JVM,可能是最快的VM周期)和OOVM(有史以来最高效的Smalltalk VM之一)。
实际上,V8的首席开发人员Lars Bak致力于其中的每一个,以及其他一些人。
高度优化JavaScript解释器的动力更大,这就是为什么我们看到Mozilla,Google和Microsoft之间投入了大量资源的原因。JavaScript必须在(通常是不耐烦的)人在等待时进行下载,解析,编译和实时运行,它必须在有人与之交互时运行,并且它是在不受控制的客户端中进行的可以是计算机,电话或烤面包机的环境。为了有效地在这些条件下运行,它必须高效。
Python和Ruby在开发人员/部署者控制的环境中运行。通常,功能强大的服务器或台式机系统的限制因素将是诸如内存或磁盘I / O之类的因素,而不是执行时间。或者在可以利用非引擎优化(例如缓存)的地方。对于这些语言,将重点放在语言和库功能集而不是速度优化上可能更有意义。
这样做的附带好处是,我们有两个出色的高性能开源JavaScript引擎,这些引擎可以并且正在重新用于所有类型的应用程序,例如Node.js。
其中很大一部分与社区有关。大多数情况下,Python和Ruby没有公司的支持。没有人获得全职从事Python和Ruby工作的报酬(尤其是他们没有获得始终从事CPython或MRI工作的报酬)。另一方面,V8得到了世界上最强大的IT公司的支持。
此外,V8可以更快,因为对V8员工唯一重要的是解释器-他们没有标准的库可以使用,也无需担心语言设计。他们只是写翻译。而已。
它与知识产权法无关。Python也不是由Google伙计共同开发的(它的创建者与其他一些提交者在那儿一起工作,但是在Python上工作他们没有得到报酬)。
Python 3的另一个障碍是Python3。它的采用似乎是语言开发人员的主要关注点,以至于他们冻结了新语言功能的开发,直到其他实现赶上来。
关于技术细节,我对Ruby不太了解,但是Python在很多地方都可以使用优化功能(Google项目Unladen Swallow在开始努力之前就开始实现这些功能)。这是他们计划的一些优化。如果为CPython实现JIT la PyPy,我可以看到Python在将来获得V8的速度,但这在未来几年似乎不太可能(目前的重点是采用Python 3,而不是JIT)。
许多人还认为Ruby和Python可以从删除各自的全局解释器锁中受益匪浅。
您还必须了解Python和Ruby都是比JS重得多的语言-它们以标准库,语言功能和结构的方式提供了更多内容。单独的面向对象的类系统增加了很多权重(我认为这是一种很好的方式)。我几乎认为Javascript是一种旨在嵌入的语言,例如Lua(在许多方面,它们是相似的)。Ruby和Python具有更丰富的功能集,而表现力通常是以速度为代价的。
误导性的问题。V8是JavaScript的JIT(即时编译器)实现,在其最流行的非浏览器实现Node.js中,它是围绕事件循环构建的。CPython不是JIT,也不是事件。但是这些在PyPy项目中最普遍地存在于Python中-一个兼容CPython 2.7(不久将成为3.0+)的JIT。并且有大量事件服务器库,例如Tornado。在运行Tornado与Node.js的PyPy之间存在真实的测试,并且性能差异很小。
由于不同的设计优先级和用例目标,我相信。
通常,脚本(aka动态)语言的主要目的是成为本机函数调用之间的“胶水”。这些本机功能应a)覆盖最关键/经常使用的区域,并且b)尽可能有效。
这是一个示例: 导致iOS Safari冻结 的jQuery排序冻结是由于过度使用了按选择器调用而引起的。如果按选择器获取将以本机代码实现并且有效,那么根本就不会出现这样的问题。
考虑ray-tracer演示,它是V8演示的常用演示。在Python世界中,由于Python提供了本机扩展的所有功能,因此可以用本机代码实现。但是在V8领域(客户端沙箱)中,您没有其他选择,只能使VM发挥更大的作用。因此,唯一的选择是使用脚本代码来查看ray-tracer的实现。
因此有不同的优先事项和动机。
在Sciter中,我通过本地实现几乎完整的jQurey核心进行了测试。在诸如ScIDE(由HTML / CSS / Script制成的IDE)之类的实际任务上,我相信这种解决方案比任何VM优化都有效。
就像V8只是JS的实现一样,CPython也是Python的一种实现。Pypy具有与V8匹配的性能。
此外,还存在可感知的性能问题:由于V8本质上是非阻塞的,因此Web开发人员可以节省更多的IO等待,从而导致性能更高的项目。V8主要用于以IO为关键的dev Web,因此他们将其与类似项目进行了比较。但是您可以在Web开发人员之外的许多其他领域中使用Python。您甚至可以使用C扩展来完成许多任务,例如科学计算或加密,并以出色的性能处理数据。
但是在网络上,最流行的Python和Ruby项目正在阻止。尤其是Python,它具有同步WSGI标准的遗产,像著名的Django之类的框架都基于它。
您可以编写异步Python(例如Twisted,Tornado,gevent或asyncio)或Ruby。但是它并不经常执行。最好的工具仍在阻塞。
但是,这是为什么Ruby和Python中的默认实现没有V8这么快的一些原因。
就像JörgW Mittag指出的那样,从事V8工作的人都是VM天才。Python是一群热情的开发人员,在很多领域都非常擅长,但并不擅长VM调优。
Python软件基金会的资金很少:一年不到40K的资金来投资Python。当您认为像Google,Facebook或Apple这样的大公司都在使用Python时,这有点疯狂,但这是一个丑陋的事实:大多数工作都是免费完成的。自愿者在Java手工制作之前为Youtube提供支持的语言。
他们是聪明而敬业的志愿者,但是当他们确定自己在田间需要更多果汁时,就无法要求30万聘请该领域的顶尖专家。他们必须四处寻找免费提供服务的人。
在此有效的同时,这意味着您必须非常注意自己的优先事项。因此,现在我们需要查看:
即使具有最新的现代功能,编写Java脚本也很糟糕。您遇到范围问题,集合极少,可怕的字符串和数组操作,几乎没有日期,数学和正则表达式之外的stdlist,甚至对于非常常见的操作也没有语法糖。
但是在V8中,您已经有了速度。
这是因为,速度是Google的主要目标,因为它是Chrome浏览器页面渲染的瓶颈。
在Python中,可用性是主要目标。因为这几乎从来不是项目的瓶颈。这里的稀缺资源是开发人员时间。针对开发人员进行了优化。
因为JavaScript实现不需要关心其绑定的向后兼容性。
直到最近,JavaScript实现的唯一用户还是Web浏览器。由于安全性要求,仅Web浏览器供应商有权通过向运行时编写绑定来扩展功能。因此,无需保持绑定的C API向后兼容,可以允许Web浏览器开发人员随着JavaScript运行时的发展来更新其源代码。他们反正一起工作。甚至是V8,它是游戏的后来者,也是由一个非常有经验的开发人员领导的,随着它变得越来越好,它也改变了API。
OTOH Ruby(主要)用于服务器端。许多流行的ruby扩展都被编写为C绑定(考虑RDBMS驱动程序)。换句话说,如果不保持兼容性,Ruby永远不会成功。
今天,这种差异在一定程度上仍然存在。使用node.js的开发人员抱怨说,随着V8随着时间的推移更改API,很难保持其本机扩展向后兼容(这是node.js被派生的原因之一)。在这方面,IIRC红宝石仍采取更为保守的方法。
由于JIT,曲轴,类型推断器和数据优化代码,V8速度很快。标记指针,NaN标记双打。当然,它在中间进行常规的编译器优化。
普通的ruby,python和perl引擎都不会做这些,而只是进行一些基本的优化。
唯一接近的主要虚拟机是luajit,它甚至不进行类型推断,常量折叠,NaN标记或整数,但是使用类似的小代码和数据结构,不如不良语言那么胖。我的原型动态语言potion和p2具有与luajit类似的功能,并且胜过v8。使用可选的类型系统“渐进式键入”,您可以轻松超越v8,因为您可以绕过曲轴。参见飞镖。
已知的优化后端(如pypy或jruby)仍然遭受各种过度设计技术的困扰。