Bun

基准测试

Bun 旨在实现速度。热路径经过广泛的分析和基准测试。Bun 所有公共基准测试的源代码可以在 Bun 仓库的 /bench 目录中找到。

测量时间

为了精确测量时间,Bun 提供了两个运行时 API 函数:

  1. Web 标准的 performance.now() 函数
  2. Bun.nanoseconds(),它与 performance.now() 类似,但返回自应用程序启动以来以纳秒为单位的时间。您可以使用 performance.timeOrigin 将其转换为 Unix 时间戳。

基准测试工具

在编写自己的基准测试时,选择正确的工具很重要。

  • 对于微基准测试,一个很好的通用工具是 mitata
  • 对于负载测试,您必须使用一个至少与 Bun.serve() 一样快的 HTTP 基准测试工具,否则您的结果将产生偏差。一些流行的基于 Node.js 的基准测试工具,如 autocannon,速度不够快。我们推荐以下工具之一:
  • 对于脚本或 CLI 命令的基准测试,我们推荐 hyperfine

测量内存使用

Bun 有两个堆。一个堆用于 JavaScript 运行时,另一个堆用于其他所有内容。

#

JavaScript 堆统计

bun:jsc 模块公开了几个用于测量内存使用情况的函数。

import { heapStats } from "bun:jsc";
console.log(heapStats());

查看示例统计信息

JavaScript 是一种垃圾回收语言,而不是引用计数语言。在某些情况下,对象不会立即被释放是正常且正确的,但对象永远不会被释放则不正常。

强制手动运行垃圾回收

Bun.gc(true); // synchronous
Bun.gc(false); // asynchronous

堆快照允许您检查哪些对象未被释放。您可以使用 bun:jsc 模块拍摄堆快照,然后使用 Safari 或 WebKit GTK 开发者工具进行查看。要生成堆快照:

import { generateHeapSnapshot } from "bun";

const snapshot = generateHeapSnapshot();
await Bun.write("heap.json", JSON.stringify(snapshot, null, 2));

要查看快照,请在 Safari 的开发者工具(或 WebKit GTK)中打开 heap.json 文件。

  1. 打开开发者工具
  2. 点击“Timeline”(时间线)
  3. 点击左侧菜单中的“JavaScript Allocations”(JavaScript 分配)。在点击铅笔图标显示所有时间线之前,它可能不可见。
  4. 点击“Import”(导入)并选择您的堆快照 JSON 文件。
Import heap json
导入堆快照

导入后,您应该会看到类似以下内容:

Viewing heap snapshot in Safari
在 Safari 开发者工具中查看堆快照

Web 调试器 Web debugger 还提供了时间线功能,允许您跟踪和检查正在运行的调试会话的内存使用情况。

原生堆统计

Bun 使用 mimalloc 来处理其他堆。要报告非 JavaScript 内存使用情况的摘要,请设置 MIMALLOC_SHOW_STATS=1 环境变量,统计信息将在退出时打印。

MIMALLOC_SHOW_STATS=1 bun script.js

# will show something like this:
heap stats:    peak      total      freed    current       unit      count
  reserved:   64.0 MiB   64.0 MiB      0       64.0 MiB                        not all freed!
 committed:   64.0 MiB   64.0 MiB      0       64.0 MiB                        not all freed!
     reset:      0          0          0          0                            ok
   touched:  128.5 KiB  128.5 KiB    5.4 MiB   -5.3 MiB                        ok
  segments:      1          1          0          1                            not all freed!
-abandoned:      0          0          0          0                            ok
   -cached:      0          0          0          0                            ok
     pages:      0          0         53        -53                            ok
-abandoned:      0          0          0          0                            ok
 -extended:      0
 -noretire:      0
     mmaps:      0
   commits:      0
   threads:      0          0          0          0                            ok
  searches:     0.0 avg
numa nodes:       1
   elapsed:       0.068 s
   process: user: 0.061 s, system: 0.014 s, faults: 0, rss: 57.4 MiB, commit: 64.0 MiB