时间分析

本节介绍如何分析使用 Rust 和 WebAssembly 的 Web 页面。还有改善吞吐量或延迟。

⚡ 评测时,请始终确保使用优化的构建!默认情况下,wasm build 生成将使用优化进行生成。

可用工具

window.performance.now() 计时器

performance.now() 返回加载网页后以毫秒为单位的单调时间戳。

调用 performance.now() 的开销很小,因此我们可以从中创建简单的、细粒度的度量,而不会扭曲系统其余部分的性能,也不会对度量造成偏差。

我们可以使用它来计时各种操作,并且可以通过 web-sys crate 访问 window.performance.now()

  1. extern crate web_sys;
  2. fn now() -> f64 {
  3. web_sys::window()
  4. .expect("should have a Window")
  5. .performance()
  6. .expect("should have a Performance")
  7. .now()
  8. }

参考

开发者工具分析器

所有 Web 浏览器的内置开发者工具都包含一个分析器。 这些分析器显示哪些函数花费最多时间,表现形式为可视化类型,如调用树和火焰图。

如果你使用调试符号进行构建,使 “name” 自定义部分包含在 wasm 二进制文件中,那么这些分析器应该显示 Rust 函数名称,而不是像 wasm-function[123] 这样的不透明内容。

请注意,这些分析器不会显示内联函数,而且由于 Rust 和 LLVM 非常依赖内联,因此结果可能仍然有点令人费解。

profiler-with-rust-names

参考

console.timeconsole.timeEnd 函数

console.timeconsole.timeEnd 函数 允许你将命名操作的计时记录到浏览器的开发人员工具控制台。 操作开始时调用 console.time("some operation"),完成时调用 console.timeEnd("some operation")。 命名操作的字符串标签是可选的。

你可以通过 web-sys crate 直接使用这些功能:

以下是浏览器控制台中 console.time 日志的屏幕截图:

console-time

此外,console.timeconsole.timeEnd 日志将显示在浏览器分析器的 “时间线” 或 “瀑布” 视图中:

console-time-in-profiler

使用原生代码 #[bench]

我们通常可以通过编写 #[test] 来利用操作系统的本机代码调试工具,而不是在 Web 上进行调试,同样,我们也可以通过编写 #[bench] 函数来利用操作系统的本机代码分析工具。

在子目录 benches 中,写下你的基准。确保你的 crate-type 包括 “rlib”,否则基准二进制文件将无法链接你的主 lib。 确保你的 crate-type 包含 “rlib”,否则 bench 二进制文件将无法链接你的主lib。

然而!在投入大量精力进行本机代码评测之前,请确保你知道瓶颈在 WebAssembly 中! 使用浏览器的分析器来确认这一点,否则你可能会浪费时间优化不常用的代码。

参考