WebAssembly 入门:Rust 编译 WASM + JS 调用

Choyeon· 2026年9月1日· 2 分钟阅读· 503 阅读· 479 字· 1,424 字符
WebAssembly 入门:Rust 编译 WASM + JS 调用

前端遇到图像/矩阵/密码学等 CPU 密集任务时,JS 性能成瓶颈。WebAssembly 让 Rust 代码编译为接近原生速度的字节码。

工具链与基础绑定

安装 wasm-pack 后,用 #[wasm_bindgen] 宏把 Rust 函数导出为 JS 可调用形式。复杂结构用 serde + serde_wasm_bindgen 序列化跨语言传递。

use wasm_bindgen::prelude::*;
use serde::{Serialize, Deserialize};
use web_sys::console;

#[derive(Serialize, Deserialize)]
pub struct MatrixResult { rows: usize, cols: usize, data: Vec<f64>, compute_ms: f64 }

#[wasm_bindgen(start)]
pub fn init() {
    console_error_panic_hook::set_once();
    console::log_1(&"[WASM] Matrix module loaded".into());
}

#[wasm_bindgen]
pub fn matrix_multiply(a_ptr: *mut f64, a_rows: usize, a_cols: usize, b_ptr: *mut f64, b_cols: usize) -> JsValue {
    use std::time::Instant;
    let t0 = Instant::now();
    let a = unsafe { std::slice::from_raw_parts(a_ptr, a_rows * a_cols) };
    let b = unsafe { std::slice::from_raw_parts(b_ptr, a_cols * b_cols) };
    let mut c = vec![0.0f64; a_rows * b_cols];
    for i in 0..a_rows {
        for k in 0..a_cols {
            let aik = a[i * a_cols + k];
            let rb = &b[k * b_cols..(k + 1) * b_cols];
            let rc = &mut c[i * b_cols..(i + 1) * b_cols];
            for j in 0..b_cols { rc[j] += aik * rb[j]; }
        }
    }
    let r = MatrixResult { rows: a_rows, cols: b_cols, data: c, compute_ms: t0.elapsed().as_secs_f64() * 1000.0 };
    serde_wasm_bindgen::to_value(&r).unwrap()
}

#[wasm_bindgen]
pub fn fibonacci_iter(n: u32) -> u64 {
    if n <= 1 { return n as u64; }
    let (mut prev, mut curr) = (0u64, 1u64);
    for _ in 2..=n { let next = prev.saturating_add(curr); prev = curr; curr = next; }
    curr
}

#[wasm_bindgen(js_name = "allocateFloat64Array")]
pub fn allocate_f64(len: usize) -> *mut f64 {
    let mut v = Vec::with_capacity(len);
    let p = v.as_mut_ptr();
    std::mem::forget(v);
    p
}

JS 调用与内存共享

WASM 内存是共享 ArrayBuffer,通过 TypedArray 视图直接读写比参数序列化快 10-100 倍。大数据时直接分配内存给 JS 端填充,再传指针和尺寸给 WASM。

对比项 纯 JS WASM (Rust) 加速倍数 适用场景
矩阵乘法 1024x1024 ~1800ms ~85ms ~21x 3D/游戏/AI推理
Fibonacci(n=40) ~980ms ~8ms ~120x 数学计算
SHA-256 1MB ~42ms ~6ms ~7x 密码学/校验

最佳实践

适合计算密集型循环,不要做 DOM 操作。优先 TypedArray 共享内存而非大对象参数,发布构建用 wasm-opt 优化体积。

本文作者

评论 (0)

暂无评论,来抢沙发吧。