008 Web Assembly之效能分析

linghuyichong發表於2021-08-23

影片地址:www.bilibili.com/video/BV1eg411g7c...
相關原始碼:github.com/anonymousGiga/Rust-and-...

本節我們將改進實現的生命遊戲的效能,我們將利用時間分析來指導我們的工作。

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可以看到已經可以在介面上顯示幀率了。

我們使用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檢視相關的效能。

本作品採用《CC 協議》,轉載必須註明作者和本文連結
令狐一衝

相關文章