2 ポイント 投稿者 GN⁺ 2024-07-31 | 1件のコメント | WhatsAppで共有

ゼロから作られた実験的な AOT JS エンジン

Porfforは、JSコードをWebAssemblyまたはネイティブに事前コンパイルするユニークなJSエンジン/コンパイラ/ランタイムです。現在は研究目的で使われており、実運用での利用には制約があります。

Wasm コンパイル

PorfforのWebAssembly出力は、既存のJS -> Wasmプロジェクトと比べてはるかに高速かつ小型です。これは、PorfforがJSをAOTでコンパイルするためです。

  • Wasmサイズ: Javyより 32倍小さい (~1.3MB -> ~40KB)
  • Wasm性能: Javyより 18倍高速 (~70m -> ~4m)

ネイティブコンパイル

JSを事前コンパイルするため、Porfforはランタイムを同梱せずに実際のネイティブバイナリへコンパイルできます。これにより、次のような結果が得られます。

  • バイナリサイズ: 1000倍以上小さい (~90MB -> <50KB)
  • メモリ使用量: 40倍以上少ない (~50MB -> ~1MB)
  • 性能: 最大3倍高速

追加事項

  • Porfforは安全: Wasmにコンパイルされ、メモリ安全な言語(JS)で書かれています。
  • Porfforは最初からAOTを念頭に置いて設計: 既存のJSエンジンをベースにしていません。唯一の依存関係はJSパーサーです。
  • PorfforはTypeScript入力をサポート: 面倒なトランスパイラ段階は不要です。TSファイルをそのまま入力できます。

Playground

Porfforはオンラインまたはローカルで試せます。npm i -g porffor@latest && porf コマンドを使えばOKです。

  • Prime Numbers
  • Fibonacci
  • Factorial
  • Sum of Digits
  • Exception
  • Array Reading
  • ArrayPrototype
  • Math Proposals Parser: acorn, meriyah, hermes-parser, @babel/parser
  • Target: wasm
const isPrime = number => {
  if (number < 2) return false;
  for (let i = 2; i < number; i++) {
    if (number % i == 0) return false;
  }
  return true;
}

let counter = 0;
while (counter <= 10000) {
  if (isPrime(counter)) Porffor.numberLog(counter);
  counter++;
}

Test262

Test262は、公式のECMAScript準拠テストスイートです。Porfforは各コミットごとにこれを実行し、準拠の進捗を追跡しています。

GN⁺のまとめ

Porfforは、JSコードをWebAssemblyまたはネイティブに事前コンパイルするユニークなエンジンです。これにより、既存ソリューションと比べてはるかに小さいサイズと高速な性能を実現します。研究目的で使われており、TypeScript入力もサポートしています。このプロジェクトは、JSエンジンの性能と効率を研究するうえで有用かもしれません。類似機能を持つプロジェクトとしては、JavyのようなJS -> Wasmコンパイラがあります。

1件のコメント

 
GN⁺ 2024-07-31
Hacker News の意見
  • Oliver が Porffor に専念すると発表した
  • JS の性能向上には限界があり、V8 の C++ 呼び出しにトランスパイルするのが最善ではないかという意見がある
    • TypeScript をコンパイルすると大きな性能向上が得られる
    • TS と V8 は急速に変化する非標準の対象なので、大規模なチームが必要になる
  • JS ランタイムが Wasm へのアプローチを試みているのは面白いと思う
    • Static Hermes と Porffor の共通点と相違点を分析している
      • どちらも JS の test262 準拠を目標にしている
      • Porffor は Native と Wasm 出力をサポートするが、Static Hermes は主に Native 出力に注力している
      • Porffor はセルフホストで純粋な JS で書かれており、Static Hermes は LLVM に依存している
      • Porffor は非同期/Promise/await をサポートしていないが、Static Hermes は限定的にサポートしている
      • Static Hermes は C++ で書かれており、Porffor は主に JS で書かれている
      • どちらも TypeScript をサポートしているが、Static Hermes は TS AST を Flow にトランスパイルし、Porffor はネイティブでサポートしている
      • Static Hermes は eval のような難しい JS シナリオをサポートするためのフォールバックインタープリタを持っているが、Porffor は AOT コンパイルのみをサポートしている
  • このプロジェクトが JS エンジンを高速化できるのではないかと期待されている
  • windmill.dev では、ユーザーがコードをデプロイする際に Bun ビルドを使ってスクリプトとすべての依存関係を 1 つの js ファイルにバンドルしている
    • バンドルを s3 に保存して、コールドスタートとメモリ使用量を改善している
    • すべてをネイティブにバンドルできるなら、ゲームチェンジャーになるだろう
  • "ahead-of-time JS engine" が "JS-to-Wasm compiler" より良い説明なのはなぜかと疑問に思っている
  • Porffor のバージョン管理方式には疑問がある
    • Test262 テストでリグレッションが発生すると、バージョン番号が逆行する可能性がある
  • Porffor はウェールズ語で「紫」を意味する
  • quickJS と比べて、JS をネイティブコードにコンパイルする方法が気になる
  • Facebook が PHP を C にトランスパイルしようとしていたときと同じ発想だと思う
    • hiphop-php と呼ばれていて、最終的には新しい概念として hhvm を作った
  • NodeJS をネイティブライブラリにコンパイルする方法が知りたい
    • 現在使っているプロセスは少し複雑で、エラーが起きやすい