【问题标题】:Without eval(), can JavaScript be compiled into binaries?如果没有 eval(),JavaScript 可以编译成二进制文件吗?
【发布时间】:2011-02-19 15:10:39
【问题描述】:

从我读过的所有内容来看,似乎唯一提到的阻止 JavaScript 编译一次、到处运行(或至少每个浏览器运行)的是愚蠢的 eval() 语句。 JavaScript 还有什么其他的东西使这成为不可能的壮举吗?

与其浪费所有时间,在每台计算机和每一个浏览器上,JIT-ting 和下载多个源代码文件,我希望看到浏览器以更少的字节、更少的连接和极快的速度运行 JavaScript ,优化代码。

如何做到这一点?

【问题讨论】:

  • 可以使用eval编译代码,你只需要访问eval的实现。这不仅仅是理论。 Cython,它编译 Python(嗯,一个几乎完美的 Python 超集,带有与 C 接口的扩展)。还有几个 Lisp 实现是静态编译的,虽然我不知道他们是否对eval 的使用施加了任何限制。
  • Javascript是解释而不是编译,但是很多开发者使用compressor来减少电线上的文件。当代码包含eval 语句时,一些压缩器(如 YUI)拒绝修改作用域变量名称。但是如果你确信你的eval 语句不会受到修改的伤害,你可以使用window.eval 来规避这种保护。
  • @samshull 有诸如即时编译器之类的东西,目前所有主要引擎都在使用它来显着加快 JavaScript 的执行速度,因此您现在在浏览器上运行的 JavaScript 可能很好编译
  • @yi-jang,您的建议基于这样的想法,即编译后的代码可以被信任不会导致任何数量的恶意副作用,包括(但不限于)内存泄漏和缓冲区溢出。但总有 Chromium 的NativeClient

标签: javascript compiler-construction performance


【解决方案1】:

不过,这并没有真正浪费那么多时间。 JavaScript 引擎在运行 JavaScript 上花费的时间远远多于解析它。当然理论上你可以将 JavaScript 编译成机器代码,这有点像将 JavaScript 引擎与脚本本身一起嵌入,就像一个自解压的 ZIP 文件或其他东西。不过我看不出这样做的好处。

【讨论】:

    【解决方案2】:

    这个问题在几个层面上都有缺陷。

    1. 如果您指的是任何二进制格式(例如,字节码),那么您将需要所有 JS 实现来加强、聚集并解决标准。不会发生。即使,也不能保证你会得到任何,更不用说显着的文件大小比缩小 JS 的改进。将某些 .py 源文件的大小与我手头的缓存 .pyc 字节码文件的大小进行比较表明,至少 CPython 的字节码通常大于源文件。而且源文件甚至没有被缩小!
    2. 如果您的意思是本机可执行文件...嗯,很难将 JS 编译为本机代码 AOT,尤其是在这样做时不构建完整的实现,但理论上可能是可行的。但是它不会带来太多的性能提升,因为你不能消除动态性(至少不是静态的——JIT 编译器可以做得更好),所以你必须为此付出代价。它也有许多缺点,使其完全一文不值:
      1. 生成的二进制文件是特定于平台的。因此,要么您必须发送所有可能的二进制文件组合(这很浪费,并且需要浏览器进行额外的特殊处理),要么您必须进行嗅探并发送您认为可能适合的任何二进制文件 - 这会让任何不愿意免费提供相当多的私人信息(通过发送错误/完全没有价值的可执行文件)。
      2. 您可能会失去沙盒。本机代码在很大程度上是一个巨大的黑匣子。在浏览器中运行它也意味着浏览器会运行它从一些不受信任的来源获得的可执行代码——恶意软件的邀请。当然,除非您将整个顶级反恶意软件套件集成到每个浏览器中。我真的需要进一步评论吗?
      3. 除非您为所有实现创建一个标准,允许编译后的 JS 访问实现的所有内置函数等,或者创建某种共享代码的方式,否则您最终会产生大量冗余(静态链接整个 JS 实现)进入二进制文件)。结果可能会比压缩的 JS 大得多。
      4. 您仍然需要一些标准接口(当然,除非您想从 architectures * OSs 转到 architectures * OSs * browsers 可执行文件)用于 DOM 集成。
      5. 更不用说所有浏览器都必须支持这一点。以标准方式或各自独立。说服他们所有人以源代码形式支持大多数 HTML、CSS 和 JS 已经足够困难(而且时间很长)。或者您需要引入一些标准方法来检测对此的支持。
      6. 此外(如前所述),对于动态语言,JIT 的性能可以与静态编译器一样好或更好。所以很有可能(非常不恰当,考虑到前面的一些观点)你会节省一些下载时间(已经可以使用缩小、压缩、缓存等变得非常小)和解析(这是无论如何,这不是最大的性能杀手)。但实际运行时间也不会显着改善。

    【讨论】:

    • 感谢您的回答 - 但我绝对不是暗示我们放弃浏览器作为平台的所有好处(沙盒、操作系统/架构的抽象、标准),而只是询问是否有一种更有效的方式将 JS 从服务器传递到客户端,再到机器的堆栈。 (因此,我建议每个浏览器都有二进制文件)至于字节码的大小比缩小的 JS 小——这很好,但我无法想象普通程序的字节码比它的源代码大。
    • @Jeff:好吧,我认为这仍然需要大量工作,但收益甚微。至于字节码与源大小:取决于语言、字节码格式和编程风格,但例如我认为我从未见过比源代码更小的 CPython 字节码文件。这是有道理的,因为即使是更高级的 VM 仍然需要额外的指令来处理临时值并且通常具有更多的低级操作(例如,x.y(z) 可以是 push x; get member y; push z onto stack; call with 1 arg; - 对于复杂的嵌套表达式来说更多)。每个通常是 1-4 个字节。
    猜你喜欢
    • 1970-01-01
    • 2015-09-08
    • 2018-06-12
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多