2P by neo 2달전 | favorite | 댓글 1개

처음부터 실험적인 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 명령어를 사용하면 됨.

  • 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 컴파일러가 있음.

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는 비동기/프로미스/어웨이트를 지원하지 않지만 Static Hermes는 제한적으로 지원함
      • Static Hermes는 C++로 작성되었고, Porffor는 주로 JS로 작성됨
      • 둘 다 TypeScript를 지원하지만 Static Hermes는 TS AST를 Flow로 트랜스파일링하고, Porffor는 네이티브로 지원함
      • Static Hermes는 eval과 같은 어려운 JS 시나리오를 지원하기 위해 폴백 인터프리터를 가지고 있지만, Porffor는 AOT 컴파일만 지원함
  • 이 프로젝트가 JS 엔진을 가속화할 수 있을지 기대됨
  • windmill.dev에서는 사용자가 코드를 배포할 때 Bun 빌드를 사용하여 스크립트와 모든 종속성을 하나의 js 파일로 번들링함
    • 번들을 s3에 저장하여 콜드 스타트와 메모리 사용량을 개선함
    • 모든 것을 네이티브로 번들링할 수 있다면 게임 체인저가 될 것임
  • "ahead-of-time JS engine"이 "JS-to-Wasm compiler"보다 더 나은 설명인 이유를 궁금해함
  • Porffor의 버전 관리 방식에 대해 의심이 있음
    • Test262 테스트에서 회귀가 발생하면 버전 번호가 역행할 수 있음
  • Porffor는 웨일스어로 "보라색"을 의미함
  • quickJS와 비교하여 JS를 네이티브 코드로 컴파일하는 방법을 궁금해함
  • Facebook이 PHP를 C로 트랜스파일링하려 했던 것과 같은 아이디어라고 생각함
    • hiphop-php라고 불렸고, 결국 hhvm을 새 개념으로 만들었음
  • NodeJS를 네이티브 라이브러리로 컴파일할 수 있는 방법을 알고 싶어함
    • 현재 사용 중인 프로세스가 약간 복잡하고 오류가 발생하기 쉬움