008 Web Assembly之性能分析

JavaScript/前端
423
0
0
2022-06-13
标签   WebAssembly

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代码,整个文件如下:

<!DOCTYPE html>
<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查看相关的性能。