0 介绍
视频地址:www.bilibili.com/video/BV1eg411g7c...
相关源码:github.com/anonymousGiga/Rust-and-...
本节我们将改进实现的生命游戏的性能,我们将利用时间分析来指导我们的工作。
1 使用window.performance.now函数创建FPS timer
FPS(Frames Per Second)Timer在我们分析康威游戏的渲染速度时非常有用。
我们首先添加fps对象到wasm-game-of-life/www/index.js中:
const fps = new class { | |
constructor() { | |
this.fps = document.getElementById("fps"); | |
this.frames = []; | |
this.lastFrameTimeStamp = performance.now(); | |
} | |
render() { | |
// Convert the delta time since the last frame render into a measure | |
// of frames per second. | |
const now = performance.now(); | |
const delta = now - this.lastFrameTimeStamp; | |
this.lastFrameTimeStamp = now; | |
const fps = 1 / delta * 1000; | |
// Save only the latest 100 timings. | |
this.frames.push(fps); | |
if (this.frames.length > 100) { | |
this.frames.shift(); | |
} | |
// Find the max, min, and mean of our 100 latest timings. | |
let min = Infinity; | |
let max = -Infinity; | |
let sum = 0; | |
for (let i = 0; i < this.frames.length; i++) { | |
sum += this.frames[i]; | |
min = Math.min(this.frames[i], min); | |
max = Math.max(this.frames[i], max); | |
} | |
let mean = sum / this.frames.length; | |
// Render the statistics. | |
this.fps.textContent = ` | |
Frames per Second: | |
latest = ${Math.round(fps)} | |
avg of last 100 = ${Math.round(mean)} | |
min of last 100 = ${Math.round(min)} | |
max of last 100 = ${Math.round(max)} | |
`.trim(); | |
} | |
}; |
再添加调用的代码:
const renderLoop = () => { | |
fps.render(); //new | |
universe.tick(); | |
drawGrid(); | |
drawCells(); | |
animationId = requestAnimationFrame(renderLoop); | |
}; |
在index.html中添加标签和响应的css代码,整个文件如下:
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>game-of-life-canvas</title> | |
<style> | |
body { | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
} | |
#fps { | |
white-space: pre; | |
font-family: monospace; | |
} | |
</style> | |
</head> | |
<body> | |
<button id="play-pause"></button> | |
<div id="fps"></div> | |
<!--canvas标签是表示图像或图表--> | |
<canvas id="game-of-life-canvas"></canvas> | |
<script src="./bootstrap.js"></script> | |
</body> | |
</html> |
输入127.0.0.1:8080可以看到已经可以在界面上显示帧率了。
2 分析每个tick的时间
我们使用web-sys中的console.time和console.timeEnd来分析Universe::tick。
我们在wasm-game-of-life/Cargo.toml中添加如下:
[dependencies.web-sys] | |
version = "0.3" | |
features = [ | |
"console", | |
] |
为了方便调用,我们对console.timeEnd和console.time做如下封装:
use web_sys::console; | |
pub struct Timer<'a> { | |
name: &'a str, | |
} | |
impl<'a> Timer<'a> { | |
pub fn new(name: &'a str) -> Timer<'a> { | |
console::time_with_label(name); | |
Timer { name } | |
} | |
} | |
impl<'a> Drop for Timer<'a> { | |
fn drop(&mut self) { | |
console::time_end_with_label(self.name); | |
} | |
} |
然后我们在对应的方法中添加如下代码:
//在tick函数的第一行添加如下代码 | |
let _timer = Timer::new("Universe::tick"); |
编译后,我们可以使用F12查看相关的性能。