在本页上
deno bench
,基准测试工具
命令行用法
deno bench [OPTIONS] [files]... [-- [SCRIPT_ARG]...]
使用 Deno 的内置 bench 工具运行基准测试。
评估给定的文件,运行所有使用 'Deno.bench()' 声明的基准测试,并将结果报告到标准输出
deno bench src/fetch_bench.ts src/signal_bench.ts
如果您指定一个目录而不是一个文件,则该路径将扩展到所有包含与 glob {*_,*.,}bench.{js,mjs,ts,mts,jsx,tsx}
匹配的文件
deno bench src/
类型检查选项 跳转到标题
--check
跳转到标题
设置类型检查行为。此子命令默认会对本地模块进行类型检查,因此添加 --check
是多余的。如果提供值 "all",则会包含远程模块。或者,可以使用 `deno check` 子命令。
--no-check
跳转到标题
跳过类型检查。如果提供值 "remote",则将忽略来自远程模块的诊断错误。
依赖管理选项 跳转到标题
--cached-only
跳转到标题
要求远程依赖项已缓存。
--frozen
跳转到标题
如果锁文件过期,则报错。
--import-map
跳转到标题
从本地文件或远程 URL 加载导入映射文件。
--lock
跳转到标题
检查指定的锁文件。(如果没有提供值,则默认为 "./deno.lock")。
--no-lock
跳转到标题
禁用锁文件的自动发现。
--no-npm
跳转到标题
不解析 npm 模块。
--no-remote
跳转到标题
不解析远程模块。
--node-modules-dir
跳转到标题
设置 npm 包的 node_modules 管理模式。
--reload
跳转到标题
简写:-r
重新加载源代码缓存(重新编译 TypeScript),无值则重新加载所有内容。例如:jsr:@std/http/file-server,jsr:@std/assert/assert-equals 重新加载特定模块;npm: 重新加载所有 npm 模块;npm:chalk 重新加载特定的 npm 模块。
--vendor
跳转到标题
切换为远程模块使用本地 vendor 文件夹,以及为 npm 包使用 node_modules 文件夹。
选项 跳转到标题
--allow-scripts
跳转到标题
允许为给定包运行 npm 生命周期脚本。注意:脚本仅在使用 node_modules 目录 (--node-modules-dir
) 时才会执行。
--cert
跳转到标题
从 PEM 编码文件中加载证书颁发机构。
--config
跳转到标题
简写:-c
配置 Deno 的不同方面,包括 TypeScript、代码检查和代码格式化。通常,配置文件名为 deno.json
或 deno.jsonc
,并会被自动检测;在这种情况下,不需要此标志。
--env-file
跳转到标题
从本地文件加载环境变量。对于给定的键,只使用第一个环境变量。现有的进程环境变量不会被覆盖。
--ext
跳转到标题
设置所提供文件的内容类型。
--filter
跳转到标题
运行基准测试,基准测试名称中包含此字符串或正则表达式模式。
--ignore
跳转到标题
忽略文件。
--json
跳转到标题
不稳定:以 JSON 格式输出基准测试结果。
--location
跳转到标题
某些 Web API 使用的 globalThis.location 的值。
--no-config
跳转到标题
禁用自动加载配置文件。
--no-run
跳转到标题
缓存基准测试模块,但不运行基准测试。
--seed
跳转到标题
设置随机数生成器种子。
--v8-flags
跳转到标题
要查看所有可用标志的列表,请使用 --v8-flags=--help
。标志也可以通过 DENO_V8_FLAGS 环境变量设置。使用此标志设置的任何标志都将附加在 DENO_V8_FLAGS 环境变量之后。
文件监视选项 跳转到标题
--no-clear-screen
跳转到标题
在监视模式下不清除终端屏幕。
--watch
跳转到标题
监视文件更改并自动重启进程。仅监视入口点模块图中的本地文件。
--watch-exclude
跳转到标题
从监视模式中排除提供的文件/模式。
快速入门 跳转到标题
首先,我们创建一个文件 url_bench.ts
并使用 Deno.bench()
函数注册一个基准测试。
// url_bench.ts
Deno.bench("URL parsing", () => {
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 parsing 17.29 µs/iter (16.67 µs … 153.62 µs) 17.25 µs 18.92 µs 22.25 µs
编写基准测试 跳转到标题
要定义基准测试,您需要使用 Deno.bench
API 进行注册。此 API 有多个重载,以实现最大的灵活性并在不同形式之间轻松切换(例如,当您需要快速集中单个基准测试进行调试时,使用 only: true
选项)。
// Compact form: name and function
Deno.bench("hello world #1", () => {
new URL("https://deno.land");
});
// Compact form: named function.
Deno.bench(function helloWorld3() {
new URL("https://deno.land");
});
// Longer form: bench definition.
Deno.bench({
name: "hello world #2",
fn: () => {
new URL("https://deno.land");
},
});
// Similar to compact form, with additional configuration as a second argument.
Deno.bench("hello world #4", { permissions: { read: true } }, () => {
new URL("https://deno.land");
});
// Similar to longer form, with bench function as a second argument.
Deno.bench(
{ name: "hello world #5", permissions: { read: true } },
() => {
new URL("https://deno.land");
},
);
// Similar to longer form, with a named bench function as a second argument.
Deno.bench({ permissions: { read: true } }, function helloWorld6() {
new URL("https://deno.land");
});
异步函数 跳转到标题
您还可以通过传递返回 Promise 的基准测试函数来对异步代码进行基准测试。为此,您可以在定义函数时使用 async
关键字。
Deno.bench("async hello world", async () => {
await 1;
});
关键代码段 跳转到标题
有时,基准测试用例需要包含设置和拆卸代码,这些代码会影响基准测试结果。例如,如果您想测量读取一个小文件所需的时间,您需要打开文件、读取它,然后关闭它。如果文件足够小,打开和关闭文件所需的时间可能会超过读取文件本身所需的时间。
为了处理这种情况,您可以使用 Deno.BenchContext.start
和 Deno.BenchContext.end
来告诉基准测试工具您想要测量的关键代码段。这两个调用之间的代码段之外的所有内容都将被排除在测量之外。
Deno.bench("foo", async (b) => {
// Open a file that we will act upon.
const file = await Deno.open("a_big_data_file.txt");
// Tell the benchmarking tool that this is the only section you want
// to measure.
b.start();
// Now let's measure how long it takes to read all of the data from the file.
await new Response(file.readable).arrayBuffer();
// End measurement here.
b.end();
// Now we can perform some potentially time-consuming teardown that will not
// taint out benchmark results.
file.close();
});
分组和基线 跳转到标题
注册基准测试用例时,可以使用 Deno.BenchDefinition.group
选项将其分配到一个组。
// url_bench.ts
Deno.bench("url parse", { 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()
您可以在同一个文件中指定多个组。
运行基准测试 跳转到标题
要运行基准测试,请使用包含基准测试函数的文件调用 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}
结尾的文件。
# Run all benches in the current directory and all sub-directories
deno bench
# Run all benches in the util directory
deno bench util/
# Run just my_bench.ts
deno bench my_bench.ts
⚠️ 如果您想将额外的 CLI 参数传递给基准测试文件,请使用
--
通知 Deno 其余参数是脚本参数。
# Pass additional arguments to the bench file
deno bench my_bench.ts -- -e --foo --bar
deno bench
使用与 deno run
相同的权限模型,因此需要例如 --allow-write
才能在基准测试期间写入文件系统。
要查看 deno bench
的所有运行时选项,您可以参考命令行帮助。
deno help bench
过滤 跳转到标题
有许多选项可以过滤您正在运行的基准测试。
命令行过滤 跳转到标题
可以使用命令行 --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 正则表达式的语法糖一样。
基准测试定义过滤 跳转到标题
在基准测试本身中,您有两个过滤选项。
过滤掉(忽略这些基准测试) 跳转到标题
有时您希望根据某些条件忽略基准测试(例如,您只希望基准测试在 Windows 上运行)。为此,您可以使用基准测试定义中的 ignore
布尔值。如果将其设置为 true,则基准测试将被跳过。
Deno.bench({
name: "bench windows feature",
ignore: Deno.build.os !== "windows",
fn() {
// do windows feature
},
});
筛选(仅运行这些基准测试)跳转到标题
有时您可能正在处理大型基准测试类中的性能问题,并且您希望只关注单个基准测试并暂时忽略其余部分。为此,您可以使用 only
选项来告诉基准测试工具仅运行将此选项设置为 true 的基准测试。多个基准测试可以设置此选项。虽然基准测试运行会报告每个基准测试的成功或失败,但如果任何基准测试标记了 only
,则整个基准测试运行将始终失败,因为这只是一项临时措施,它禁用了几乎所有基准测试。
Deno.bench({
name: "Focus on this bench only",
only: true,
fn() {
// bench complicated stuff
},
});
JSON 输出 跳转到标题
要以 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
}
}
]
}