常规的JavaScript可以转换为asm.js吗,还是只能用于加速静态类型的低级语言?
常规的JavaScript可以转换为asm.js吗,还是只能用于加速静态类型的低级语言?
我阅读了问题\"How to test and develop with asm.js?\",并且被接受的答案提供了一个链接到\"http://kripken.github.com/mloc_emscripten_talk/#/\"的网页。\n那个幻灯片的结论是\"静态类型语言,尤其是C / C ++,可以有效地编译成JavaScript\",所以我们可以\"预期编译后的C / C ++的速度在今年晚些时候达到比本机代码慢2倍或更好\"。\n但是那么对于非静态类型的语言,比如常规的JavaScript本身呢?它能被编译成asm.js吗?
可以将正常的JavaScript转换为asm.js吗,还是只能用来加速静态类型的低级语言?
这个问题的出现原因是因为asm.js是一种用于提高性能的静态类型语言,而JavaScript是一种动态类型语言。因此,将普通的JavaScript转换为asm.js是不可能的。asm.js的存在意味着JavaScript JIT(即时编译器)的开发人员放弃了他们的承诺,即JavaScript将在没有开发人员努力的情况下变得更快。
解决方法是使用合适的工具来完成任务。如果你想要静态且性能非常高的代码,可以使用C/C++(或Java);如果你想要一种动态语言,可以使用JavaScript、Python等。任何图灵完备的语言都可以转换为其他图灵完备的语言。
尽管可能存在转换的可能性,但并不意味着这是一个明智的做法。根据其他回答,虽然可能实现转换,但不会获得任何性能上的好处。类比一下,如果一个孩子伸手去碰一个热炉子,告诉他们“碰那个炉子是不可能的,别试了”既不正确也没有用。
需要注意的是,解释和编译并不相同。编译到类似ASM.js的子集中会包括一些即时解释无法实现的优化。Flow和TypeScript通过理解开发人员在开发过程中使用的常见习惯来展示了这个概念。此外,如果程序员愿意放弃一些语言特性,编译器的工作只需去除语法糖即可。
关于JavaScript为什么还没有演变成静态类型语言的问题,这是一个合理的问题。图灵对类型转换没有意见,而编译器则有。
普通的JavaScript不能直接转换为asm.js,因为它们是不同的语言类型。想要使用asm.js来提高性能,可以使用静态类型的低级语言如C/C++或Java。
可以将常规JavaScript转换为asm.js吗,还是只能加快静态类型的低级语言?这个问题的出现是因为人们想知道是否可以将常规JavaScript转换为asm.js以提高性能。然而,作者认为这样做并不能带来性能上的好处。他将这个问题比喻为尝试压缩已经压缩过的文件,虽然可以运行压缩算法,但通常不会得到更小的文件。
为了理解这一点,我们需要了解为什么asm.js能提供性能优势,或者更一般地说,为什么静态类型语言比动态类型语言执行得更好。简短的答案是"运行时类型检查需要时间",更详细的答案包括静态类型代码优化的可行性更高。举例来说,如果x和y都是已知的整数,我可以将函数c优化为一些机器代码指令。如果它们既可以是整数也可以是字符串,优化问题变得更加困难;我必须在某些情况下将它们视为字符串连接,而在其他情况下视为加法。特别地,在c中发生的加法操作有四种可能的解释;它可以是加法,也可以是字符串连接,或者是两种不同的强制转换为字符串并连接的变体。随着可能的类型增加,可能的排列组合数量也增加;在动态类型语言的最坏情况下,对于涉及n个项的表达式,有k^n个可能的解释,每个项可能有任意数量的k个类型。在静态类型语言中,k=1,因此任何给定表达式都只有1种解释。因此,优化器在搜索优化机会时在优化静态类型代码时更加高效。
转换从动态类型代码到静态类型代码(从JavaScript到asm.js)时,必须考虑原始代码的语义。这意味着类型检查仍然发生(只是现在已经在静态类型代码中明确表示),并且所有这些排列组合仍然存在以扼杀编译器。
另外一点是:在JavaScript的编译过程中,通过投入处理器时间,确实可以获得性能上的好处,例如使用闭包编译器;部分原因是在构建过程中,你有更多的时间深入研究类型推断问题,而不是在浏览器中。原则上,我可以想象使用asm.js作为这个步骤的更有效的输出介质;也就是说,一些关于类型的有用信息在转换回原始JavaScript时可能会丢失。实际上,我猜测任何这样的好处都是不可观察到的。
虽然可以将常规JavaScript转换为asm.js,但并不会带来性能上的明显好处。这是因为动态类型语言的性能成本来自于代码的含义,而具有相同含义的静态类型程序将具有相同的成本。动态类型代码转换为静态类型代码时,必须考虑原始代码的语义,并且所有可能的排列组合仍然存在以阻碍编译器。
问题的出现原因:JavaScript的动态性导致无法直接编译为asm.js。如果要将JavaScript编译成asm.js,就需要使用一个虚拟机来处理那些非静态的特性。但是,asm.js是一个相对受限的JavaScript子集,可以很容易地转换为字节码。然而,为了获得这种优势,你首先需要将所有JavaScript的高级特性分解为asm.js子集,这是一项相当复杂的任务。而JavaScript引擎则被设计和优化为将所有这些高级特性直接转换为字节码,所以为什么要费事地使用asm.js这样的中间步骤呢?
解决方法:将JavaScript代码编译成静态二进制文件的想法并不现实,因为如果可以轻松将JS的动态特性编译成静态二进制文件,浏览器早就会内置AOT编译器来处理标准JS,这样将JS转换为asm.js就变得多余了。
所以,总结起来,由于JavaScript的动态性,不可能直接将其编译为asm.js。如果要将JavaScript代码转换为asm.js,需要先将其转换为静态的asm.js子集,然后再进行编译。但是,由于JavaScript引擎已经被优化为直接将高级特性转换为字节码,所以这个中间步骤并不是必需的。