7

我正在尝试将使用 Pythonic 语义编写的代码自动编译/转换为本机和快速的 Javascript 代码。

什么工具可以做到这一点,并且可以像 Java 等那样提供良好的调试支持?

有人做过吗?

为什么?

我正在尝试编写一些具有复杂主循环、时间线、一些物理模拟和一些复杂交互的可视化代码。IE:这是一个实际的 CPU 绑定问题。

使用 Javascript 编写并在其浏览器环境中进行测试比在像样的 IDE 中运行的 Java、.NET 或 Python 更难调试。但是对于使用复杂的客户端代码进行实际的大规模Web开发,如果不是直接编写的话,至少需要编译成Javascript。

背景:最新进展

Emscripten 允许将 C/C++ 编译为 Javascript,由于 ArrayBuffer 的类型化数组支持和新的浏览器 JS 引擎,它可以在浏览器中以更高的效率运行,因为ASM.jsLLJS利用了 Mozilla 最近的速度改进(其他供应商可能很快就会跟随)。

Altjs.org有一份 Javascript 替代方案的清单,但还没有特别关注最近的速度改进或良好的语义,但人们使用更好的工具为浏览器编写代码已成为普遍的地方。特别是 Emscripten 有大量令人惊叹的演示

已经考虑的可能选项:

  • Shedskin - 目前我已经尝试让 Shedskin 工作,但我的 C++/C 技能有限(Emscripten 只为它使用的受 Boehm 启发的垃圾收集器公开了一个 C API,而 Shedskin 需要一个 C++ 垃圾收集类来处理它的对象,但它不存在然而)。
  • Unladen Swallow / RPython,到 LLVM - 还不能在 Ubuntu 上正确设置
  • Boo 到 Java,然后到 LLVM(还不能在我的 Ubuntu 系统上设置)

附加约束:

  • 我需要在我的 Ubuntu 系统上使用它。
  • 编译后的 Javascript 应该可能小于 1 MB
  • 使用同样交叉编译的本机语言进行调试应该仍然是可能的,允许利用现有的调试工具。

“这个构建指令表的过程应该非常有趣。它没有成为苦力的真正危险,因为任何非常机械的过程都可能交给机器本身。” ——艾伦·M·图灵,1946

4

2 回答 2

2

您想要一种可以编译为高效低级 JavaScript 的高级动态语言吗?哪有这回事。如果动态语言速度很快,我们一开始就不需要 asm.js。

如果您想编写可编译为高效 JavaScript 的代码,则必须学习较低级别的语言。Emscripten 速度快的原因是它从低级语言 (C/C++) 编译,与常规 JavaScript 相比,它允许更好的编译器优化。这也是为什么 asm.js 和 LLVM 可以更快的原因。它们的速度来自没有动态类型、垃圾收集(特别是这使得使用 ArrayBuffer 作为内存成为可能)和其他高级特性。

底线是。不存在将具有 Pythonic 语义的语言编译成本机和快速 Javascript 代码的工具。并且根据您所说的语义,这种事情不太可能出现,因为 Python 本身就是一种慢速语言。

目前生成快速 JavaScript 的最佳选择是 Emscripten。您也可以考虑使用 LLJS 或手动编写快速的 JavaScript(Chrome 有这方面的调试工具)。

此外,考虑到您的问题的标题,您非常关心语法。你不应该。在为工作选择正确的语言时,语法是最不重要的因素之一。

于 2013-03-25T09:36:45.817 回答
1

既然你自己提到了 shedskin,我想你可以分享一些你的经验(并解释你认为 shedskin 到底缺少什么,除了它的输入是受限制的 python 语法)。我还可以假设 Cython/Pyrex 是不可接受的(由于语法限制)。

如果 shedskin 在 alpha 阶段对你来说太多了,那么你可能正在寻找像Numba项目这样的东西,它包括将动态 python 编译到 LLVM 以及 llvm-py,它允许链接 LLVM 暴露的字节码,类似于 ctypes 允许链接共享库并构建 LLVM IR 编译器。

这是博客的一部分,其中展示了如何将 Numba 用作 numpy 的 JIT(包括与等效 Cython 代码的性能比较):

import numpy as np
from numba import double
from numba.decorators import jit

@jit(arg_types=[double[:,:], double[:,:]])
def pairwise_numba(X, D):
    M = X.shape[0]
    N = X.shape[1]
    for i in range(M):
        for j in range(M):
            d = 0.0
            for k in range(N):
                tmp = X[i, k] - X[j, k]
                d += tmp * tmp
            D[i, j] = np.sqrt(d)

Emscripten 应该允许您公开和调用您的 python -> llvm -> JS 代码,如下所述:https ://github.com/kripken/emscripten/wiki/Interacting-with-code

于 2013-07-22T21:35:03.797 回答