在当前页面
deno bench
,基准测试工具
命令行用法
o bench [选项] [文件]... [-- [脚本参数]...]
使用 Deno 内置的基准测试工具运行基准测试。
评估给定文件,运行所有使用 'Deno.bench()' 声明的基准测试,并将结果报告到标准输出:
deno bench src/fetch_bench.ts src/signal_bench.ts
如果指定的是目录而不是文件,路径将扩展为所有匹配 glob {*_,*.,}bench.{js,mjs,ts,mts,jsx,tsx}
的包含文件:
deno bench src/
了解更多: https://docs.deno.com/go/bench
不稳定选项 Jump to heading
--unstable
Jump to heading
--unstable
标志已被弃用。请使用细粒度的 --unstable-*
标志.
--unstable-bare-node-builtins
Jump to heading
启用不稳定的裸 Node 内置功能.
--unstable-broadcast-channel
Jump to heading
启用不稳定的 BroadcastChannel
API.
--unstable-cron
Jump to heading
启用不稳定的 Deno.cron API.
--unstable-detect-cjs
Jump to heading
在更多情况下将模棱两可的 .js, .jsx, .ts, .tsx 文件视为 CommonJS 模块.
--unstable-kv
Jump to heading
启用不稳定的键值存储 API.
--unstable-net
Jump to heading
启用不稳定的网络 API.
--unstable-node-globals
Jump to heading
在所有地方暴露 Node 全局变量.
--unstable-sloppy-imports
Jump to heading
启用不稳定的通过扩展探测、.js 到 .ts 以及目录探测来解析模块说明符.
--unstable-temporal
Jump to heading
启用不稳定的 Temporal API.
--unstable-unsafe-proto
Jump to heading
启用不安全的 proto 支持。这是一个安全风险。.
--unstable-webgpu
Jump to heading
启用不稳定的 WebGPU
API.
--unstable-worker-options
Jump to heading
启用不稳定的 Web Worker API.
类型检查选项 Jump to heading
--check
Jump to heading
设置类型检查行为。此子命令默认会检查本地模块,因此添加 --check
是多余的
如果提供了 "all" 值,远程模块将被包含。
或者,可以使用 'deno check' 子命令.
--no-check
Jump to heading
跳过类型检查。如果提供了 "remote" 值,远程模块的诊断错误将被忽略.
依赖管理选项 Jump to heading
--cached-only
Jump to heading
要求远程依赖已经缓存.
--frozen
Jump to heading
如果锁文件过期则报错.
--import-map
Jump to heading
从本地文件或远程 URL 加载导入映射文件 文档:https://docs.deno.com/runtime/manual/basics/import_maps.
--lock
Jump to heading
检查指定的锁文件。(如果未提供值,默认为 "./deno.lock").
--no-lock
Jump to heading
禁用自动发现锁文件.
--no-npm
Jump to heading
不解析 npm 模块.
--no-remote
Jump to heading
不解析远程模块.
--node-modules-dir
Jump to heading
设置 npm 包的 node 模块管理模式.
--reload
Jump to heading
Short flag: -r
重新加载源代码缓存(重新编译 TypeScript) 无值 重新加载所有内容 jsr:@std/http/file-server,jsr:@std/assert/assert-equals 重新加载特定模块 npm: 重新加载所有 npm 模块 npm:chalk 重新加载特定 npm 模块.
--vendor
Jump to heading
切换远程模块的本地 vendor 文件夹和 npm 包的 node_modules 文件夹的使用.
Options Jump to heading
--allow-scripts
Jump to heading
允许运行给定包的 npm 生命周期脚本
注意:只有在使用 node_modules 目录时才会执行脚本(--node-modules-dir
).
--cert
Jump to heading
从 PEM 编码文件加载证书颁发机构.
--config
Jump to heading
Short flag: -c
配置 deno 的不同方面,包括 TypeScript、代码格式化和代码检查
通常配置文件将被称为 deno.json
或 deno.jsonc
并自动检测;在这种情况下,此标志不是必需的。
文档:https://docs.deno.com/go/config.
--env-file
Jump to heading
从本地文件加载环境变量 仅使用具有给定键的第一个环境变量。 现有的进程环境变量不会被覆盖,因此如果环境中已经存在具有相同名称的变量,它们的值将被保留。 如果 .env 文件中有多个相同环境变量的声明,则应用第一个遇到的声明。这由您作为参数传递的文件的顺序决定。.
--ext
Jump to heading
设置提供文件的内容类型.
--filter
Jump to heading
运行基准测试名称中包含此字符串或正则表达式模式的基准测试.
--ignore
Jump to heading
忽略文件.
--json
Jump to heading
不稳定:以 JSON 格式输出基准测试结果.
--location
Jump to heading
某些 web API 使用的 globalThis.location 的值.
--no-config
Jump to heading
禁用自动加载配置文件.
--no-run
Jump to heading
缓存基准测试模块,但不运行基准测试.
--permit-no-files
Jump to heading
如果未找到基准测试文件,则不返回错误代码.
--seed
Jump to heading
设置随机数生成器种子.
--v8-flags
Jump to heading
要查看所有可用标志的列表,请使用 --v8-flags=--help
标志也可以通过 DENO_V8_FLAGS 环境变量设置。
使用此标志设置的任何标志都会附加在 DENO_V8_FLAGS 环境变量之后.
文件监视选项 Jump to heading
--no-clear-screen
Jump to heading
在监视模式下不清除终端屏幕.
--watch
Jump to heading
监视文件更改并自动重启进程。 仅监视入口点模块图中的本地文件。.
--watch-exclude
Jump to heading
从监视模式中排除提供的文件/模式.
快速开始 Jump to heading
首先,我们创建一个文件 url_bench.ts
,并使用 Deno.bench()
函数注册一个基准测试。
// url_bench.ts
Deno.bench("URL 解析", () => {
new URL("https://deno.land");
});
其次,使用 deno bench
子命令运行基准测试。
deno bench url_bench.ts
cpu: Apple M1 Max
runtime: deno 1.21.0 (aarch64-apple-darwin)
file:///dev/deno/url_bench.ts
benchmark time (avg) (min … max) p75 p99 p995
--------------------------------------------------- -----------------------------
URL 解析 17.29 µs/iter (16.67 µs … 153.62 µs) 17.25 µs 18.92 µs 22.25 µs
编写基准测试 Jump to heading
要定义一个基准测试,你需要通过调用 Deno.bench
API 来注册它。该 API
有多个重载,以提供最大的灵活性,并允许在不同形式之间轻松切换(例如,当你需要快速专注于单个基准测试进行调试时,可以使用
only: true
选项):
// 紧凑形式:名称和函数
Deno.bench("hello world #1", () => {
new URL("https://deno.land");
});
// 紧凑形式:命名函数。
Deno.bench(function helloWorld3() {
new URL("https://deno.land");
});
// 较长形式:基准测试定义。
Deno.bench({
name: "hello world #2",
fn: () => {
new URL("https://deno.land");
},
});
// 类似于紧凑形式,第二个参数为附加配置。
Deno.bench("hello world #4", { permissions: { read: true } }, () => {
new URL("https://deno.land");
});
// 类似于较长形式,第二个参数为基准测试函数。
Deno.bench(
{ name: "hello world #5", permissions: { read: true } },
() => {
new URL("https://deno.land");
},
);
// 类似于较长形式,第二个参数为命名的基准测试函数。
Deno.bench({ permissions: { read: true } }, function helloWorld6() {
new URL("https://deno.land");
});
异步函数 Jump to heading
你也可以通过传递一个返回 promise
的基准测试函数来测试异步代码。为此,你可以在定义函数时使用 async
关键字:
Deno.bench("async hello world", async () => {
await 1;
});
关键部分 Jump to heading
有时,基准测试用例需要包含设置和清理代码,这些代码可能会影响基准测试结果。例如,如果你想测量读取一个小文件所需的时间,你需要打开文件、读取它,然后关闭它。如果文件足够小,打开和关闭文件所需的时间可能会超过读取文件本身的时间。
为了帮助处理这种情况,你可以使用 Deno.BenchContext.start
和
Deno.BenchContext.end
来告诉基准测试工具你想要测量的关键部分。这两个调用之间的部分将被排除在测量之外。
Deno.bench("foo", async (b) => {
// 打开一个我们将要操作的文件。
using file = await Deno.open("a_big_data_file.txt");
// 告诉基准测试工具这是你唯一想要测量的部分。
b.start();
// 现在让我们测量从文件中读取所有数据所需的时间。
await new Response(file.readable).arrayBuffer();
// 在此结束测量。
b.end();
});
上述示例需要 --allow-read
标志来运行基准测试:deno bench --allow-read file_reading.ts
。
分组和基线 Jump to heading
在注册基准测试用例时,可以使用 Deno.BenchDefinition.group
选项将其分配到一个组中:
// url_bench.ts
Deno.bench("url 解析", { group: "url" }, () => {
new URL("https://deno.land");
});
将多个用例分配到一个组中并比较它们与“基线”用例的性能是很有用的。
在这个例子中,我们将检查 Date.now()
与 performance.now()
的性能,为此我们将第一个用例标记为“基线”,使用 Deno.BenchDefinition.baseline
选项:
// time_bench.ts
Deno.bench("Date.now()", { group: "timing", baseline: true }, () => {
Date.now();
});
Deno.bench("performance.now()", { group: "timing" }, () => {
performance.now();
});
$ deno bench time_bench.ts
cpu: Apple M1 Max
runtime: deno 1.21.0 (aarch64-apple-darwin)
file:///dev/deno/time_bench.ts
benchmark time (avg) (min … max) p75 p99 p995
--------------------------------------------------------- -----------------------------
Date.now() 125.24 ns/iter (118.98 ns … 559.95 ns) 123.62 ns 150.69 ns 156.63 ns
performance.now() 2.67 µs/iter (2.64 µs … 2.82 µs) 2.67 µs 2.82 µs 2.82 µs
summary
Date.now()
21.29x times faster than performance.now()
你可以在同一个文件中指定多个组。
运行基准测试 Jump to heading
要运行基准测试,请使用包含基准测试函数的文件调用
deno bench
。你也可以省略文件名,在这种情况下,当前目录(递归)中匹配 glob
{*_,*.,}bench.{ts, tsx, mts, js, mjs, jsx}
的所有基准测试都将运行。如果你传递一个目录,该目录中匹配此 glob
的所有文件都将运行。
glob 扩展为:
- 名为
bench.{ts, tsx, mts, js, mjs, jsx}
的文件, - 或以
.bench.{ts, tsx, mts, js, mjs, jsx}
结尾的文件, - 或以
_bench.{ts, tsx, mts, js, mjs, jsx}
结尾的文件
# 运行当前目录和所有子目录中的所有基准测试
deno bench
# 运行 util 目录中的所有基准测试
deno bench util/
# 仅运行 my_bench.ts
deno bench my_bench.ts
⚠️ 如果你想将额外的 CLI 参数传递给基准测试文件,请使用
--
来告知 Deno 剩余的参数是脚本参数。
# 将额外参数传递给基准测试文件
deno bench my_bench.ts -- -e --foo --bar
deno bench
使用与 deno run
相同的权限模型,因此需要例如 --allow-write
来在基准测试期间写入文件系统。
要查看 deno bench
的所有运行时选项,你可以参考命令行帮助:
deno help bench
过滤 Jump to heading
有许多选项可以过滤你正在运行的基准测试。
命令行过滤 Jump to heading
可以使用命令行 --filter
选项单独或分组运行基准测试。
过滤标志接受字符串或模式作为值。
假设有以下基准测试:
Deno.bench({
name: "my-bench",
fn: () => {/* bench function zero */},
});
Deno.bench({
name: "bench-1",
fn: () => {/* bench function one */},
});
Deno.bench({
name: "bench2",
fn: () => {/* bench function two */},
});
此命令将运行所有这些基准测试,因为它们都包含“bench”一词。
deno bench --filter "bench" benchmarks/
另一方面,以下命令使用模式,将运行第二个和第三个基准测试。
deno bench --filter "/bench-*\d/" benchmarks/
要让 Deno 知道你想使用模式,请用正斜杠包裹你的过滤器,就像 JavaScript 中正则表达式的语法糖。
基准测试定义过滤 Jump to heading
在基准测试本身中,你有两个过滤选项。
过滤掉(忽略这些基准测试) Jump to heading
有时你想根据某种条件忽略基准测试(例如,你只希望在 Windows
上运行基准测试)。为此,你可以在基准测试定义中使用 ignore
布尔值。如果设置为
true,基准测试将被跳过。
Deno.bench({
name: "bench windows feature",
ignore: Deno.build.os !== "windows",
fn() {
// do windows feature
},
});
过滤进(仅运行这些基准测试) Jump to heading
有时你可能在一个大型基准测试类中遇到性能问题,并且你希望暂时只专注于该单个基准测试,而忽略其余部分。为此,你可以使用
only
选项来告诉基准测试工具仅运行将此选项设置为 true
的基准测试。多个基准测试可以设置此选项。虽然基准测试运行将报告每个基准测试的成功或失败,但如果任何基准测试被标记为
only
,则整个基准测试运行将始终失败,因为这只是临时措施,禁用了几乎所有基准测试。
Deno.bench({
name: "Focus on this bench only",
only: true,
fn() {
// bench complicated stuff
},
});
JSON 输出 Jump to heading
要获取 JSON 格式的输出,请使用 --json
标志:
$ deno bench --json bench_me.js
{
"runtime": "Deno/1.31.0 x86_64-apple-darwin",
"cpu": "Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz",
"benches": [
"origin": "file:///dev/bench_me.js",
"group": null,
"name": "Deno.UnsafePointerView#getUint32",
"baseline": false,
"result": {
"ok": {
"n": 49,
"min": 1251.9348,
"max": 1441.2696,
"avg": 1308.7523755102038,
"p75": 1324.1055,
"p99": 1441.2696,
"p995": 1441.2696,
"p999": 1441.2696
}
}
]
}