Bun

Bun v0.6.2


Jarred Sumner · 5月17日, 2023

我們正在招募 C/C++ 和 Zig 工程師,一同打造 JavaScript 的未來! 查看職位列表 →

這次更新包含針對 minifier 和 bundler 的幾個錯誤修復,以及 JavaScript 效能的提升,感謝 JavaScriptCore 團隊成員 @Constellation 和 @shvaikalesh。

如果您還沒看過,請務必查看 Bun v0.6.0 的發布說明。

curl
npm
brew
docker
curl
curl -fsSL https://bun.dev.org.tw/install | bash
npm
npm install -g bun
brew
brew tap oven-sh/bun
brew install bun
docker
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun

升級 Bun

bun upgrade

toLocaleString() 效能提升 79 倍

感謝 @Constellation,數字的 toLocaleString() 效能提升了 79 倍。

toLocaleString 將數字轉換為目前地區設定預期的字串格式。

這會影響像這樣的程式碼

const myNumber = 123;

myNumber.toLocaleString();
  • https://github.com/WebKit/WebKit/pull/13860

JSON.parse 效能最高提升 20% & JSON.stringify 效能提升 15%

感謝 @Constellation,在沒有太多巢狀物件的物件上,JSON.parse 效能提升了 20%,而 JSON.stringify 在相同情境下效能提升了 15%。

之前

cpu: Apple M1 Max
runtime: bun 0.6.1 (arm64-darwin)

benchmark                time (avg)             (min … max)       p75       p99      p995
----------------------------------------------------------- -----------------------------
JSON.parse(obj)        1.45 µs/iter     (1.32 µs … 2.99 µs)   1.38 µs   2.99 µs   2.99 µs
JSON.stringify(obj)  612.71 ns/iter   (556.91 ns … 1.35 µs) 586.41 ns   1.35 µs   1.35 µs

之後 (數字越低越好)

cpu: Apple M1 Max
runtime: bun 0.6.2 (arm64-darwin)

benchmark                time (avg)             (min … max)       p75       p99      p995
----------------------------------------------------------- -----------------------------
JSON.parse(obj)         1.1 µs/iter   (999.92 ns … 2.08 µs)   1.04 µs   2.08 µs   2.08 µs
JSON.stringify(obj)  546.45 ns/iter   (489.78 ns … 1.68 µs) 518.86 ns  979.2 ns   1.68 µs

Node.js,作為比較

cpu: Apple M1 Max
runtime: node v20.1.0 (arm64-darwin)

benchmark                time (avg)             (min … max)       p75       p99      p995
----------------------------------------------------------- -----------------------------
JSON.parse(obj)        2.44 µs/iter     (2.34 µs … 2.59 µs)   2.51 µs   2.59 µs   2.59 µs
JSON.stringify(obj)    1.38 µs/iter     (1.33 µs … 1.47 µs)   1.42 µs   1.47 µs   1.47 µs

查看微基準測試

  • https://github.com/WebKit/WebKit/pull/13898
  • https://github.com/WebKit/WebKit/pull/13480 (請注意,這裡列出的基準測試適用於整個應用程式,而非特別針對 JSON.parse 的微基準測試)
  • https://github.com/oven-sh/WebKit/commit/3fa658700239c8e7cbe8fa20793a6314274560cd

Proxy 效能提升

感謝 @shvaikalesh 的一系列 PR,透過 Proxy 取得或設定屬性時,效能提升了 2 倍以上。

  • https://github.com/WebKit/WebKit/pull/13349
  • https://github.com/WebKit/WebKit/pull/13408
  • https://github.com/WebKit/WebKit/pull/13660

Object.assign 搭配空物件效能提升

感謝 @Constellation,以空物件作為第二個參數的 Object.assign() 效能提升了 2 倍。

function test(options) {
  var options = Object.assign({ defaultParam: 32 }, options);
  return options;
}

// empty object as the 2nd arguemnt to object assign
test({});
  • https://github.com/WebKit/WebKit/pull/13220/files

回傳 arguments 效能提升 2 倍

同樣感謝 @Constellation,在函式中回傳 arguments 的效能提升了 2 倍

function test(a, b, c) {
  return arguments;
}

for (var i = 0; i < 1e6; ++i) test(0, 1, 2);
  • https://github.com/WebKit/WebKit/pull/13304

Minifier 錯誤:與樣板字串相關

由於 bun 解析器中樣板字面值內部的 rope 字串邏輯不正確,像這樣的程式碼有時會產生不正確的字串

const foo = ".*";
const regex1 = new RegExp(foo); // Invalid regular expression: unmatched parentheses
const regex2 = new RegExp(`(${foo})`);

這個問題已修復,感謝 @dylan-conway

資源名稱重寫錯誤

當執行

bun build ./foo.js

如果 foo.js 類似這樣

foo.js
import MyAsset from './asset.svg';

bun build 會回報以下錯誤


  foo.js                        0.00 KB

  asset-bcd3157c264ff68c.svg    0.00 KB

[6ms] bundle 2 modules

...然後永遠不會將 asset-bcd3157c264ff68c.svg 複製到輸出目錄。

這個問題已修復 (並改善了測試覆蓋率),感謝 @dylan-conway

警告訊息會導致建置失敗

Bun 針對建置相關錯誤有不同的日誌層級。只有 error 日誌層級的訊息才應該導致建置失敗,但一個錯誤導致任何訊息都會使建置失敗。

這表示,例如,像這樣的程式碼

const Foo = <Bar key="123" {...props} />;

會導致建置失敗,因為它在使用 key 和展開運算符時發出警告。

那是一個錯誤,並且已修復,感謝 @paperclover