常规 JavaScript 可以转换为 asm.js,还是只是为了加速静态类型的低级语言?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15626611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 01:26:59  来源:igfitidea点击:

Can regular JavaScript be converted to asm.js, or is it only to speed up statically-typed low-level languages?

javascriptasm.js

提问by Oriol

I have read the question How to test and develop with asm.js?, and the accepted answer gives a link to http://kripken.github.com/mloc_emscripten_talk/#/.

我已经阅读了如何使用 asm.js 进行测试和开发的问题,并且接受的答案提供了指向http://kripken.github.com/mloc_emscripten_talk/#/的链接。

The conclusion of that slide show is that "Statically-typed languages and especially C/C++ can be compiled effectively to JavaScript", so we can "expect the speed of compiled C/C++ to get to just 2X slower than native code, or better, later this year".

该幻灯片的结论是“静态类型语言,尤其是 C/C++ 可以有效地编译为 JavaScript”,因此我们可以“期望编译后的 C/C++ 的速度仅比本机代码慢 2 倍,或者更好,今年晚些时候”。

But what about non-statically-typed languages, such as regular JavaScript itself? Can it be compiled to asm.js?

但是非静态类型语言呢,比如常规 JavaScript 本身呢?可以编译成asm.js吗?

采纳答案by Bergi

Can JavaScript itself be compiled to asm.js?

JavaScript 本身可以编译成 asm.js 吗?

Not really, because of its dynamic nature. It's the same problem as when trying to compile it to Cor even to native code- you actually would need to ship a VM with it to take care of those non-static aspects. At least, such a VM is possible:

不是真的,因为它是动态的。这与尝试将其编译为 C或什至本地代码时遇到的问题相同- 您实际上需要随附一个 VM 来处理这些非静态方面。至少,这样的 VM 是可能的:

js.jsis a JavaScript interpreter in JavaScript. Instead of trying to create an interpreter from scratch, SpiderMonkeyis compiled into LLVMand then emscriptentranslates the output into JavaScript.

js.js是 JavaScript 中的 JavaScript 解释器。SpiderMonkey不是尝试从头开始创建解释器,而是编译到LLVM 中,然后emscripten将输出转换为 JavaScript。

But if asmjs code runs faster than regular JS, then it makes sense to compile JS to asmjs, no?

但是如果 asmjs 代码比普通 JS 运行得更快,那么将 JS 编译为 asmjs 是有意义的,不是吗?

No. asm.jsis a quite restricted subset of JS that can be easily translated to bytecode. Yet you first would need to break down all the advanced features of JS to that subset for getting this advantage - a quite complicated task imo. But JavaScript engines are designed and optimized to translate all those advanced features directlyinto bytecode - so why bother about an intermediate step like asm.js? Js.js claims to be around 200 times slower than "native" JS.

。asm.js是一个非常受限制的 JS 子集,可以很容易地转换为字节码。然而,您首先需要将 JS 的所有高级功能分解为该子集才能获得此优势 - 这是一项非常复杂的任务 imo。但是 JavaScript 引擎经过设计和优化,可以将所有这些高级功能直接转换为字节码 - 那么为什么要为像 asm.js 这样的中间步骤而烦恼呢?Js.js 声称比“原生”JS 慢 200 倍左右。

And what about non-statically-typed languages in general?

那么一般的非静态类型语言呢?

The slideshow talks about that from …Just C/C++?onwards. Specifically:

幻灯片从……只是 C/C++?向前。具体来说:

Dynamic Languages

Entire C/C++ runtimes can be compiled and the original language interpreted with proper semantics, but this is not lightweight

Source-to-source compilers from such languages to JavaScript ignore semantic differences (for example, numeric types)

Actually, these languages depend on special VMs to be efficient

Source-to-source compilers for them lose out on the optimizations done in those VMs

动态语言

可以编译整个 C/C++ 运行时并使用适当的语义解释原始语言,但这不是轻量级的

从这些语言到 JavaScript 的源到源编译器忽略语义差异(例如,数字类型)

实际上,这些语言依赖于特殊的虚拟机才能高效

他们的源到源编译器失去了在这些 VM 中完成的优化

回答by killscreen

In response to the general question "is it possible?" then the answer is that sure, both JavaScript and the asm.js subset are Turing complete so a translation exists.

回答一般问题“这可能吗?” 那么答案是肯定的,JavaScript 和 asm.js 子集都是图灵完备的,因此存在翻译。

Whether one should do this and expect a performance benefit is a different question. The short answer is "no, you shouldn't." I liken this to trying to compress a compressed file; yes, it is possible to run the compression algorithm, but in general you should not expect the resulting file to be smaller.

是否应该这样做并期望获得性能优势是一个不同的问题。简短的回答是“不,你不应该”。我把这比作试图压缩一个压缩文件;是的,可以运行压缩算法,但通常您不应期望生成的文件更小。

The short answer:The performance cost of dynamically-typed languages comes from the meaning of the code; a statically-typed program with an equivalent meaning would carry the same costs.

简短的回答:动态类型语言的性能成本来自代码的含义;具有相同含义的静态类型程序将承担相同的成本。

To understand this, it is important to understand whyasm.js offers a performance benefit at all; or, more generally, why statically-typed languages perform better than dynamically-typed ones. The short answer is "run-time type checking takes time," and a longer answer would include the improved feasibility of optimizing statically-typed code. For example:

要理解这一点,重要的是要理解为什么asm.js 提供了性能优势;或者,更一般地说,为什么静态类型的语言比动态类型的语言表现得更好。简短的回答是“运行时类型检查需要时间”,较长的回答将包括优化静态类型代码的改进可行性。例如:

function a(x) { return x + 1; }
function b(x) { return x - 1; }
function c(x, y) { return a(x) + b(y); }

If xand yare both known to be integers, I can optimize function cto a couple of machine code instructions. If they could be integers or strings, the optimization problem becomes much harder; I have to treat these as string appends in some cases, and addition in other cases. In particular, there are four possible interpretations of the addition operation that occurs in c; it could be addition, or string append, or two different variants of coerce-to-string-and-append. As you add more possible types, the number of possible permutations grows; in the worst case for a dynamically-typed language, you have k^npossible interpretations of an expression involving nterms which could each have any number of ktypes. In a statically typed language, k=1, so there is always 1 interpretation of any given expression. Because of this, optimizers are fundamentally more efficient at optimizing statically-typed code than dynamically-typed code: There are fewer permutations to consider when searching for opportunities to optimize.

如果xy都是整数,我可以将函数优化c为几个机器代码指令。如果它们可以是整数或字符串,优化问题就会变得更加困难;在某些情况下,我必须将它们视为字符串附加,而在其他情况下则必须将它们视为字符串附加。特别是,对发生在 中的加法运算有四种可能的解释c;它可以是加法,也可以是字符串附加,或者是强制到字符串和附加的两种不同的变体。随着您添加更多可能的类型,可能的排列数量会增加;在动态类型语言的最坏情况下,您有k^n 种可能的表达式解释,涉及n 个术语,每个术语都有任意数量的k类型。在静态类型语言中,k=1,所以任何给定的表达式总是有 1 种解释。因此,优化器在优化静态类型代码方面比动态类型代码更有效:在搜索优化机会时需要考虑的排列较少。

The point here is that when converting from dynamically-typed code to statically-typed code (as you'd be doing when going from JavaScript to asm.js), you have to account for the semantics of the original code. Meaning the type-checking still occurs (it's just now been spelled out statically-typed code) and all those permutations are still present to stifle the compiler.

这里的重点是,当从动态类型代码转换为静态类型代码时(就像从 JavaScript 转换为 asm.js 时所做的那样),您必须考虑原始代码的语义。这意味着类型检查仍然发生(它刚刚被拼写出静态类型代码)并且所有这些排列仍然存在以扼杀编译器。

回答by abergmeier

A few facts about asm.js, which hopefully make the concept clear:

关于asm.js的一些事实,希望可以使概念清晰:

  1. Yes you can write the asm.jsdialect by hand.

    If you did look at the examples for asm.js, they are very far from being user friendly. Obviously Javascript is not the front end language for creating this code.

  2. Translating vanilla Javascript to asm.jsdialect is notpossible.

    Think about it - if you already could translate standard Javascript in a fully statically manner, why would there be a need for asm.js? The sole existance of asm.jsmeans that the Javascript JIT people at some people gave up on their promise that Javascript will get faster without any effort from the developer.

    There are several reasons for this, but let's just say it would be reallyhard for the JIT to understand a dynamic language as good as a static compiler. And then probably for the developers to fully understand the JIT.

  1. 是的,您可以手动编写asm.js方言。

    如果您确实查看了asm.js的示例,就会发现它们远非用户友好。显然 Javascript 不是用于创建此代码的前端语言。

  2. 翻译香草JavaScript来asm.js方言是不是可能。

    想一想 - 如果您已经可以完全静态地翻译标准 Javascript,为什么还需要asm.jsasm.js的唯一存在意味着某些人的 Javascript JIT 人员放弃了他们的承诺,即 Javascript 将在没有开发人员任何努力的情况下变得更快。

    有几个原因,但让我们只说这是真的很难的JIT理解的动态语言不如静态编译。然后可能让开发人员完全了解 JIT。

In the end it boils down to using the right tool for the task. If you want static, very performant code, use C/ C++( / Java) - if you want a dynamic language, use Javascript, Python, ...

最后归结为使用正确的工具来完成任务。如果你想要静态的、高性能的代码,请使用C/ C++( / Java) - 如果你想要动态语言,请使用Javascript, Python, ...

回答by luiseduardohd

asm.js has been created by the need of have a small subset of javascript which can be easily optimized. If you can have a way to convert javascript to javascript/asm.js, asm.js is not needed anymore - that method can be inserted in js interpreters directly.

asm.js 是由于需要可以轻松优化的一小部分 javascript 子集而创建的。如果您有办法将 javascript 转换为 javascript/asm.js,则不再需要 asm.js - 该方法可以直接插入 js 解释器中。

回答by John Slegers

In theory, it is possible to convert / compile / transpile any JavaScript operation to asm.js if it can be expressed with the limited subset of the language present in asm.js. In practice, however, there is no tool capable of converting ordinary JavaScript to asm.js at the moment (June, 2017).

从理论上讲,如果可以使用 asm.js 中存在的语言的有限子集来表示,则可以将任何 JavaScript 操作转换/编译/转译为 asm.js。然而,在实践中,目前(2017 年 6 月)还没有能够将普通 JavaScript 转换为 asm.js 的工具。

Either way, it would make more sense to convert a language with static typingto asm.js, because static typing is a requirement of asm.js and the lack thereof one of the features of ordinary JavaScript that makes it exceptionally hard to compile to asm.js.

无论哪种方式,将具有静态类型的语言转换为 asm.js会更有意义,因为静态类型是 asm.js 的要求,而缺少静态类型是普通 JavaScript 的特性之一,这使得编译为 asm 异常困难.js。

Back in 2013, when asm.js was hot, there has been an attempt to compile a statically typed language similar to JavaScript, but both the language and the compiler seem to have been abandoned.

早在 2013 年 asm.js 火爆的时候,就有人尝试过编译类似于 JavaScript 的静态类型语言,但语言和编译器似乎都被抛弃了。

Today, in 2017, JavaScipt subsets TypeScriptand Flowwould be suitable candidates for conversion to asm.js, but the core dev teams of neither language is interested in such conversion. LLJShad a fork that could compile to asm.js, but that project is pretty much dead. ThinScriptis a much more recent attempt and is based on TypeScript, but it doesn't appear to be active either.

今天,在 2017 年,JavaScipt 子集TypeScriptFlow将是转换为 asm.js 的合适候选者,但两种语言的核心开发团队都对这种转换不感兴趣。LLJS有一个可以编译为 asm.js 的 fork,但那个项目几乎已经死了。ThinScript是最近的一次尝试,它基于 TypeScript,但它似乎也不活跃。

So, the best and easiest way to produce asm.js code is still to write your code in C/C++ and convert / compile / transpile it. However, it remains to be seen whether we'll even want to do this in the forseeable future. Web Assemblymay soon replace asm.js altogether and there's already popping up TypeScript-like languages like TurboScriptand AssemblyScriptthat convert to Web Assembly. In fact, TurboScript was originally based on ThinScript and used to compile to asm.js, but they appear to have abandoned this feature.

因此,生成 asm.js 代码的最好和最简单的方法仍然是用 C/C++ 编写代码并转换/编译/转译它。但是,在可预见的未来,我们是否甚至愿意这样做还有待观察。连接板组件可能很快就会完全取代asm.js而且也已经弹出打字稿般一样的语言TurboScriptAssemblyScript是转换为Web大会。事实上,TurboScript 最初是基于 ThinScript 来编译成 asm.js 的,但他们似乎已经放弃了这个特性。

回答by Anderson Green

It may be possible to convert regular JavaScript into ams.js by first compiling it into Cor C++, and then compiling the generated code into asm.js using Emscripten. I'm not sure if this would be practical, but it's an interesting concept nonetheless.

有可能通过第一到常规的JavaScript转换成ams.js编译成ÇC ++,然后编译生成的代码转换成使用asm.js Emscripten。我不确定这是否实用,但它仍然是一个有趣的概念。

More recently, I found another tool called NectarJSthat compiles JavaScript into WebAssembly and ASM.js.

最近,我发现了另一个名为NectarJS 的工具,可以将 JavaScript 编译成 WebAssembly 和 ASM.js。

回答by clagccs

check this http://badassjs.com/post/43420901994/asm-js-a-low-level-highly-optimizable-subset-of

检查这个http://badassjs.com/post/43420901994/asm-js-a-low-level-highly-optimizable-subset-of

basically you need check that your code would be asm.jscompatible (no coercion or type casting, you need to manage the memory, etc). The idea behind this is write your code in javascript, detect the bottle neck and do the changes in your code for use asm.js and aot compilation instead jit and dynamic compilation...is a bit PITA but you can still use javascript or other languages like c++ or better..in a near future, lljs.....

基本上你需要检查你的代码是否与asm.js兼容(没有强制或类型转换,你需要管理内存等)。这背后的想法是用javascript编写代码,检测瓶颈并在代码中进行更改以使用asm.js和aot编译而不是jit和动态编译......有点PITA但你仍然可以使用javascript或其他像 c++ 或更好的语言..在不久的将来,lljs.....