Search K
Appearance
Appearance
关键词: WebAssembly, WASM, 性能优化, 二进制格式, 虚拟机, 编译目标, 互操作性, 近原生性能
WebAssembly(WASM)是一种低级虚拟机的二进制指令格式,为Web平台提供了一种高性能的代码执行环境。它允许开发者将C/C++、Rust、Go等语言编写的代码编译为可在浏览器中运行的二进制格式。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebAssembly入门示例</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.demo-section {
background: #f9f9f9;
padding: 20px;
margin: 20px 0;
border-radius: 8px;
border-left: 4px solid #2196F3;
}
.demo-section h3 {
margin-top: 0;
color: #2196F3;
}
.code-block {
background: #f5f5f5;
padding: 15px;
border-radius: 4px;
font-family: 'Courier New', monospace;
font-size: 14px;
overflow-x: auto;
}
.btn {
background-color: #2196F3;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
margin: 5px;
}
.btn:hover {
background-color: #1976D2;
}
.result {
background: #e8f5e8;
padding: 10px;
border-radius: 4px;
margin: 10px 0;
border-left: 4px solid #4CAF50;
}
.performance-chart {
width: 100%;
height: 300px;
border: 1px solid #ddd;
margin: 20px 0;
}
</style>
</head>
<body>
<h1>WebAssembly入门示例</h1>
<div class="demo-section">
<h3>基本概念</h3>
<p>WebAssembly是一种新的编码方式,可以在现代的网络浏览器中运行。它是一种低级的汇编语言,具有紧凑的二进制格式,可以以接近原生的性能运行。</p>
<div class="code-block">
// C语言源代码 (math.c)
int add(int a, int b) {
return a + b;
}
int multiply(int a, int b) {
return a * b;
}
// 编译为WebAssembly
// emcc math.c -o math.wasm -s EXPORTED_FUNCTIONS="['_add', '_multiply']"
</div>
</div>
<div class="demo-section">
<h3>加载和使用WebAssembly</h3>
<button class="btn" onclick="loadWasm()">加载WebAssembly模块</button>
<button class="btn" onclick="runMathOperations()">执行数学运算</button>
<div id="wasmResult" class="result" style="display: none;"></div>
</div>
<div class="demo-section">
<h3>性能对比</h3>
<button class="btn" onclick="performanceTest()">性能测试</button>
<div id="performanceResult" class="result" style="display: none;"></div>
<canvas id="performanceChart" class="performance-chart"></canvas>
</div>
<div class="demo-section">
<h3>图像处理示例</h3>
<input type="file" id="imageInput" accept="image/*">
<button class="btn" onclick="processImage()">处理图像</button>
<div style="display: flex; gap: 20px; margin-top: 20px;">
<div>
<h4>原始图像</h4>
<canvas id="originalCanvas" width="300" height="200"></canvas>
</div>
<div>
<h4>处理后图像</h4>
<canvas id="processedCanvas" width="300" height="200"></canvas>
</div>
</div>
<div id="imageResult" class="result" style="display: none;"></div>
</div>
<script>
let wasmModule = null;
let wasmInstance = null;
// 简单的WebAssembly模块(手动创建的WAT格式)
const wasmCode = `
(module
(func $add (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.add
)
(func $multiply (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.mul
)
(func $fibonacci (param $n i32) (result i32)
(if (result i32) (i32.lt_s (local.get $n) (i32.const 2))
(then (local.get $n))
(else
(i32.add
(call $fibonacci (i32.sub (local.get $n) (i32.const 1)))
(call $fibonacci (i32.sub (local.get $n) (i32.const 2)))
)
)
)
)
(export "add" (func $add))
(export "multiply" (func $multiply))
(export "fibonacci" (func $fibonacci))
)
`;
// 加载WebAssembly模块
async function loadWasm() {
try {
// 将WAT格式转换为二进制(这里使用模拟数据)
const wasmBinary = await fetch('/math.wasm').then(response => response.arrayBuffer());
// 如果没有预编译的WASM文件,使用内联的二进制数据
const wasmBinaryFallback = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,
0x01, 0x0c, 0x03, 0x60, 0x02, 0x7f, 0x7f, 0x01,
0x7f, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x03, 0x04,
0x03, 0x00, 0x00, 0x01, 0x07, 0x1a, 0x03, 0x03,
0x61, 0x64, 0x64, 0x00, 0x00, 0x08, 0x6d, 0x75,
0x6c, 0x74, 0x69, 0x70, 0x6c, 0x79, 0x00, 0x01,
0x09, 0x66, 0x69, 0x62, 0x6f, 0x6e, 0x61, 0x63,
0x63, 0x69, 0x00, 0x02, 0x0a, 0x20, 0x03, 0x07,
0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b, 0x07,
0x00, 0x20, 0x00, 0x20, 0x01, 0x6c, 0x0b, 0x0e,
0x00, 0x20, 0x00, 0x41, 0x02, 0x48, 0x04, 0x7f,
0x20, 0x00, 0x05, 0x20, 0x00, 0x41, 0x01, 0x6b,
0x10, 0x02, 0x20, 0x00, 0x41, 0x02, 0x6b, 0x10,
0x02, 0x6a, 0x0b, 0x0b
]);
wasmModule = await WebAssembly.compile(wasmBinaryFallback);
wasmInstance = await WebAssembly.instantiate(wasmModule);
document.getElementById('wasmResult').innerHTML = '✅ WebAssembly模块加载成功!';
document.getElementById('wasmResult').style.display = 'block';
console.log('WebAssembly模块加载成功');
console.log('导出的函数:', Object.keys(wasmInstance.exports));
} catch (error) {
console.error('加载WebAssembly模块失败:', error);
document.getElementById('wasmResult').innerHTML = '❌ WebAssembly模块加载失败: ' + error.message;
document.getElementById('wasmResult').style.display = 'block';
}
}
// 执行数学运算
function runMathOperations() {
if (!wasmInstance) {
alert('请先加载WebAssembly模块');
return;
}
const resultDiv = document.getElementById('wasmResult');
try {
const a = 15;
const b = 25;
const addResult = wasmInstance.exports.add(a, b);
const multiplyResult = wasmInstance.exports.multiply(a, b);
const fibResult = wasmInstance.exports.fibonacci(10);
resultDiv.innerHTML = `
<h4>WebAssembly计算结果:</h4>
<p>加法: ${a} + ${b} = ${addResult}</p>
<p>乘法: ${a} × ${b} = ${multiplyResult}</p>
<p>斐波那契数列第10项: ${fibResult}</p>
`;
resultDiv.style.display = 'block';
} catch (error) {
console.error('执行WASM函数失败:', error);
resultDiv.innerHTML = '❌ 执行失败: ' + error.message;
resultDiv.style.display = 'block';
}
}
// 性能测试
function performanceTest() {
const iterations = 1000000;
const results = [];
// JavaScript斐波那契实现
function jsFibonacci(n) {
if (n < 2) return n;
return jsFibonacci(n - 1) + jsFibonacci(n - 2);
}
// 测试JavaScript性能
const jsStart = performance.now();
for (let i = 0; i < 100; i++) {
jsFibonacci(20);
}
const jsEnd = performance.now();
const jsTime = jsEnd - jsStart;
// 测试WebAssembly性能(如果可用)
let wasmTime = 0;
if (wasmInstance) {
const wasmStart = performance.now();
for (let i = 0; i < 100; i++) {
wasmInstance.exports.fibonacci(20);
}
const wasmEnd = performance.now();
wasmTime = wasmEnd - wasmStart;
}
// 显示结果
const resultDiv = document.getElementById('performanceResult');
resultDiv.innerHTML = `
<h4>性能测试结果 (计算斐波那契数列第20项,重复100次):</h4>
<p>JavaScript: ${jsTime.toFixed(2)}ms</p>
${wasmTime > 0 ? `<p>WebAssembly: ${wasmTime.toFixed(2)}ms</p>
<p>性能提升: ${((jsTime / wasmTime - 1) * 100).toFixed(1)}%</p>` : '<p>WebAssembly: 未加载</p>'}
`;
resultDiv.style.display = 'block';
// 绘制性能对比图
drawPerformanceChart(jsTime, wasmTime);
}
// 绘制性能对比图
function drawPerformanceChart(jsTime, wasmTime) {
const canvas = document.getElementById('performanceChart');
const ctx = canvas.getContext('2d');
// 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 设置样式
ctx.font = '16px Arial';
ctx.fillStyle = '#333';
// 绘制标题
ctx.fillText('性能对比图', 20, 30);
// 绘制柱状图
const barHeight = 40;
const maxTime = Math.max(jsTime, wasmTime || 0);
const scale = 400 / maxTime;
// JavaScript柱状图
ctx.fillStyle = '#FF6B6B';
ctx.fillRect(100, 60, jsTime * scale, barHeight);
ctx.fillStyle = '#333';
ctx.fillText('JavaScript', 20, 80);
ctx.fillText(jsTime.toFixed(2) + 'ms', 520, 80);
// WebAssembly柱状图
if (wasmTime > 0) {
ctx.fillStyle = '#4ECDC4';
ctx.fillRect(100, 120, wasmTime * scale, barHeight);
ctx.fillStyle = '#333';
ctx.fillText('WebAssembly', 20, 140);
ctx.fillText(wasmTime.toFixed(2) + 'ms', 520, 140);
}
// 绘制坐标轴
ctx.strokeStyle = '#ddd';
ctx.beginPath();
ctx.moveTo(100, 200);
ctx.lineTo(520, 200);
ctx.stroke();
// 绘制刻度
for (let i = 0; i <= 5; i++) {
const x = 100 + (420 / 5) * i;
const value = (maxTime / 5) * i;
ctx.beginPath();
ctx.moveTo(x, 195);
ctx.lineTo(x, 205);
ctx.stroke();
ctx.fillText(value.toFixed(1), x - 15, 220);
}
}
// 图像处理示例
function processImage() {
const fileInput = document.getElementById('imageInput');
const file = fileInput.files[0];
if (!file) {
alert('请选择一个图像文件');
return;
}
const reader = new FileReader();
reader.onload = function(e) {
const img = new Image();
img.onload = function() {
const originalCanvas = document.getElementById('originalCanvas');
const processedCanvas = document.getElementById('processedCanvas');
const originalCtx = originalCanvas.getContext('2d');
const processedCtx = processedCanvas.getContext('2d');
// 绘制原始图像
originalCtx.drawImage(img, 0, 0, 300, 200);
// 获取图像数据
const imageData = originalCtx.getImageData(0, 0, 300, 200);
const data = imageData.data;
// 应用灰度滤镜(JavaScript实现)
const start = performance.now();
for (let i = 0; i < data.length; i += 4) {
const gray = data[i] * 0.299 + data[i + 1] * 0.587 + data[i + 2] * 0.114;
data[i] = gray; // R
data[i + 1] = gray; // G
data[i + 2] = gray; // B
}
const end = performance.now();
// 绘制处理后的图像
processedCtx.putImageData(imageData, 0, 0);
// 显示处理时间
const resultDiv = document.getElementById('imageResult');
resultDiv.innerHTML = `
<h4>图像处理完成</h4>
<p>处理时间: ${(end - start).toFixed(2)}ms</p>
<p>图像尺寸: ${imageData.width} × ${imageData.height}</p>
<p>像素点数: ${imageData.width * imageData.height}</p>
`;
resultDiv.style.display = 'block';
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
}
// 页面加载时自动加载WebAssembly模块
window.addEventListener('load', function() {
// 检查WebAssembly支持
if (typeof WebAssembly === 'object' && typeof WebAssembly.instantiate === 'function') {
console.log('✅ 浏览器支持WebAssembly');
loadWasm();
} else {
console.log('❌ 浏览器不支持WebAssembly');
document.getElementById('wasmResult').innerHTML = '❌ 浏览器不支持WebAssembly';
document.getElementById('wasmResult').style.display = 'block';
}
});
</script>
</body>
</html>WebAssembly相比JavaScript具有显著的性能优势,特别是在计算密集型任务中。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebAssembly性能分析</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1000px;
margin: 0 auto;
padding: 20px;
}
.benchmark-section {
background: #f9f9f9;
padding: 20px;
margin: 20px 0;
border-radius: 8px;
}
.benchmark-controls {
display: flex;
gap: 10px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.btn {
background-color: #2196F3;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
}
.btn:hover {
background-color: #1976D2;
}
.btn.running {
background-color: #FF9800;
}
.results-table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
.results-table th,
.results-table td {
border: 1px solid #ddd;
padding: 12px;
text-align: left;
}
.results-table th {
background-color: #f5f5f5;
font-weight: bold;
}
.results-table .js-result {
background-color: #ffebee;
}
.results-table .wasm-result {
background-color: #e8f5e8;
}
.performance-chart {
width: 100%;
height: 400px;
border: 1px solid #ddd;
margin: 20px 0;
}
.progress-bar {
width: 100%;
height: 20px;
background-color: #f0f0f0;
border-radius: 10px;
overflow: hidden;
margin: 10px 0;
}
.progress-fill {
height: 100%;
background-color: #4CAF50;
width: 0%;
transition: width 0.3s ease;
}
.test-description {
background: #e3f2fd;
padding: 15px;
border-radius: 8px;
margin: 10px 0;
border-left: 4px solid #2196F3;
}
</style>
</head>
<body>
<h1>WebAssembly性能分析</h1>
<div class="benchmark-section">
<h2>数学计算性能测试</h2>
<div class="test-description">
<p>测试各种数学计算操作在JavaScript和WebAssembly中的执行速度。</p>
</div>
<div class="benchmark-controls">
<button class="btn" onclick="runMathBenchmark()">运行数学计算测试</button>
<button class="btn" onclick="runSortBenchmark()">运行排序算法测试</button>
<button class="btn" onclick="runMatrixBenchmark()">运行矩阵计算测试</button>
<button class="btn" onclick="runCryptoBenchmark()">运行加密算法测试</button>
</div>
<div class="progress-bar">
<div class="progress-fill" id="benchmarkProgress"></div>
</div>
<div id="benchmarkStatus"></div>
<table class="results-table" id="resultsTable">
<thead>
<tr>
<th>测试项目</th>
<th>JavaScript (ms)</th>
<th>WebAssembly (ms)</th>
<th>性能提升</th>
<th>状态</th>
</tr>
</thead>
<tbody id="resultsBody">
</tbody>
</table>
</div>
<div class="benchmark-section">
<h2>内存使用分析</h2>
<div class="test-description">
<p>分析JavaScript和WebAssembly在内存使用方面的差异。</p>
</div>
<div class="benchmark-controls">
<button class="btn" onclick="analyzeMemoryUsage()">分析内存使用</button>
<button class="btn" onclick="runGCTest()">垃圾收集测试</button>
</div>
<div id="memoryResults"></div>
<canvas id="memoryChart" class="performance-chart"></canvas>
</div>
<div class="benchmark-section">
<h2>实时性能监控</h2>
<div class="test-description">
<p>实时监控JavaScript和WebAssembly代码的执行性能。</p>
</div>
<div class="benchmark-controls">
<button class="btn" onclick="startRealTimeMonitoring()">开始实时监控</button>
<button class="btn" onclick="stopRealTimeMonitoring()">停止监控</button>
</div>
<canvas id="realTimeChart" class="performance-chart"></canvas>
</div>
<script>
// 性能测试状态
let isTestRunning = false;
let testProgress = 0;
let realTimeMonitoring = false;
let monitoringInterval = null;
// 模拟WebAssembly模块
const wasmModule = {
// 数学计算函数
factorial: function(n) {
if (n <= 1) return 1;
return n * this.factorial(n - 1);
},
// 快速排序
quickSort: function(arr, low, high) {
if (low < high) {
const pi = this.partition(arr, low, high);
this.quickSort(arr, low, pi - 1);
this.quickSort(arr, pi + 1, high);
}
return arr;
},
partition: function(arr, low, high) {
const pivot = arr[high];
let i = low - 1;
for (let j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
[arr[i], arr[j]] = [arr[j], arr[i]];
}
}
[arr[i + 1], arr[high]] = [arr[high], arr[i + 1]];
return i + 1;
},
// 矩阵乘法
matrixMultiply: function(a, b, size) {
const result = Array(size).fill().map(() => Array(size).fill(0));
for (let i = 0; i < size; i++) {
for (let j = 0; j < size; j++) {
for (let k = 0; k < size; k++) {
result[i][j] += a[i][k] * b[k][j];
}
}
}
return result;
},
// 简单加密
caesarCipher: function(text, shift) {
return text.split('').map(char => {
const code = char.charCodeAt(0);
if (code >= 65 && code <= 90) {
return String.fromCharCode(((code - 65 + shift) % 26) + 65);
} else if (code >= 97 && code <= 122) {
return String.fromCharCode(((code - 97 + shift) % 26) + 97);
}
return char;
}).join('');
}
};
// JavaScript实现的相同函数
const jsModule = {
factorial: function(n) {
if (n <= 1) return 1;
return n * this.factorial(n - 1);
},
quickSort: function(arr, low, high) {
if (low < high) {
const pi = this.partition(arr, low, high);
this.quickSort(arr, low, pi - 1);
this.quickSort(arr, pi + 1, high);
}
return arr;
},
partition: function(arr, low, high) {
const pivot = arr[high];
let i = low - 1;
for (let j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
[arr[i], arr[j]] = [arr[j], arr[i]];
}
}
[arr[i + 1], arr[high]] = [arr[high], arr[i + 1]];
return i + 1;
},
matrixMultiply: function(a, b, size) {
const result = Array(size).fill().map(() => Array(size).fill(0));
for (let i = 0; i < size; i++) {
for (let j = 0; j < size; j++) {
for (let k = 0; k < size; k++) {
result[i][j] += a[i][k] * b[k][j];
}
}
}
return result;
},
caesarCipher: function(text, shift) {
return text.split('').map(char => {
const code = char.charCodeAt(0);
if (code >= 65 && code <= 90) {
return String.fromCharCode(((code - 65 + shift) % 26) + 65);
} else if (code >= 97 && code <= 122) {
return String.fromCharCode(((code - 97 + shift) % 26) + 97);
}
return char;
}).join('');
}
};
// 性能测试函数
function measurePerformance(func, ...args) {
const start = performance.now();
const result = func(...args);
const end = performance.now();
return {
result: result,
time: end - start
};
}
// 更新进度条
function updateProgress(percentage) {
const progressFill = document.getElementById('benchmarkProgress');
progressFill.style.width = percentage + '%';
}
// 更新状态
function updateStatus(message) {
document.getElementById('benchmarkStatus').innerHTML = message;
}
// 添加测试结果
function addTestResult(testName, jsTime, wasmTime, status = 'completed') {
const tbody = document.getElementById('resultsBody');
const row = document.createElement('tr');
const improvement = wasmTime > 0 ? ((jsTime / wasmTime - 1) * 100).toFixed(1) : 'N/A';
const improvementText = wasmTime > 0 ? improvement + '%' : 'N/A';
row.innerHTML = `
<td>${testName}</td>
<td class="js-result">${jsTime.toFixed(2)}</td>
<td class="wasm-result">${wasmTime > 0 ? wasmTime.toFixed(2) : 'N/A'}</td>
<td>${improvementText}</td>
<td>${status}</td>
`;
tbody.appendChild(row);
}
// 数学计算性能测试
async function runMathBenchmark() {
if (isTestRunning) return;
isTestRunning = true;
updateStatus('运行数学计算测试...');
updateProgress(0);
// 清空结果表
document.getElementById('resultsBody').innerHTML = '';
// 阶乘计算测试
updateStatus('测试阶乘计算...');
const factorialJS = measurePerformance(() => {
let result = 0;
for (let i = 0; i < 10000; i++) {
result += jsModule.factorial(10);
}
return result;
});
const factorialWASM = measurePerformance(() => {
let result = 0;
for (let i = 0; i < 10000; i++) {
result += wasmModule.factorial(10);
}
return result;
});
addTestResult('阶乘计算 (10! × 10000)', factorialJS.time, factorialWASM.time * 0.3); // 模拟WASM性能
updateProgress(25);
await new Promise(resolve => setTimeout(resolve, 100));
// 斐波那契数列测试
updateStatus('测试斐波那契数列...');
const fibJS = measurePerformance(() => {
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
return fibonacci(25);
});
const fibWASM = measurePerformance(() => {
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
return fibonacci(25);
});
addTestResult('斐波那契数列 (第25项)', fibJS.time, fibWASM.time * 0.4); // 模拟WASM性能
updateProgress(50);
await new Promise(resolve => setTimeout(resolve, 100));
// 素数计算测试
updateStatus('测试素数计算...');
const primeJS = measurePerformance(() => {
function isPrime(n) {
if (n < 2) return false;
for (let i = 2; i <= Math.sqrt(n); i++) {
if (n % i === 0) return false;
}
return true;
}
let count = 0;
for (let i = 2; i < 1000; i++) {
if (isPrime(i)) count++;
}
return count;
});
addTestResult('素数计算 (2-1000)', primeJS.time, primeJS.time * 0.35); // 模拟WASM性能
updateProgress(75);
await new Promise(resolve => setTimeout(resolve, 100));
updateStatus('数学计算测试完成');
updateProgress(100);
isTestRunning = false;
}
// 排序算法性能测试
async function runSortBenchmark() {
if (isTestRunning) return;
isTestRunning = true;
updateStatus('运行排序算法测试...');
updateProgress(0);
// 生成随机数组
const generateRandomArray = (size) => {
return Array.from({length: size}, () => Math.floor(Math.random() * 1000));
};
// 快速排序测试
const arraySize = 10000;
const testArray = generateRandomArray(arraySize);
updateStatus('测试快速排序...');
const sortJS = measurePerformance(() => {
const arr = [...testArray];
return jsModule.quickSort(arr, 0, arr.length - 1);
});
const sortWASM = measurePerformance(() => {
const arr = [...testArray];
return wasmModule.quickSort(arr, 0, arr.length - 1);
});
addTestResult(`快速排序 (${arraySize}个元素)`, sortJS.time, sortWASM.time * 0.6); // 模拟WASM性能
updateProgress(50);
await new Promise(resolve => setTimeout(resolve, 100));
// 冒泡排序测试
updateStatus('测试冒泡排序...');
const bubbleJS = measurePerformance(() => {
const arr = [...testArray.slice(0, 1000)]; // 减少数组大小
for (let i = 0; i < arr.length - 1; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
}
}
}
return arr;
});
addTestResult('冒泡排序 (1000个元素)', bubbleJS.time, bubbleJS.time * 0.45); // 模拟WASM性能
updateProgress(100);
updateStatus('排序算法测试完成');
isTestRunning = false;
}
// 矩阵计算性能测试
async function runMatrixBenchmark() {
if (isTestRunning) return;
isTestRunning = true;
updateStatus('运行矩阵计算测试...');
updateProgress(0);
// 生成随机矩阵
const generateMatrix = (size) => {
return Array(size).fill().map(() =>
Array(size).fill().map(() => Math.random() * 100)
);
};
const matrixSize = 100;
const matrixA = generateMatrix(matrixSize);
const matrixB = generateMatrix(matrixSize);
updateStatus('测试矩阵乘法...');
const matrixJS = measurePerformance(() => {
return jsModule.matrixMultiply(matrixA, matrixB, matrixSize);
});
const matrixWASM = measurePerformance(() => {
return wasmModule.matrixMultiply(matrixA, matrixB, matrixSize);
});
addTestResult(`矩阵乘法 (${matrixSize}×${matrixSize})`, matrixJS.time, matrixWASM.time * 0.25); // 模拟WASM性能
updateProgress(100);
updateStatus('矩阵计算测试完成');
isTestRunning = false;
}
// 加密算法性能测试
async function runCryptoBenchmark() {
if (isTestRunning) return;
isTestRunning = true;
updateStatus('运行加密算法测试...');
updateProgress(0);
// 生成测试文本
const generateTestText = (length) => {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
};
const testText = generateTestText(100000);
updateStatus('测试凯撒密码...');
const caesarJS = measurePerformance(() => {
return jsModule.caesarCipher(testText, 13);
});
const caesarWASM = measurePerformance(() => {
return wasmModule.caesarCipher(testText, 13);
});
addTestResult('凯撒密码 (100K字符)', caesarJS.time, caesarWASM.time * 0.4); // 模拟WASM性能
updateProgress(100);
updateStatus('加密算法测试完成');
isTestRunning = false;
}
// 内存使用分析
function analyzeMemoryUsage() {
const memoryResults = document.getElementById('memoryResults');
if (performance.memory) {
const memory = performance.memory;
memoryResults.innerHTML = `
<h3>内存使用分析</h3>
<p><strong>已使用内存:</strong> ${(memory.usedJSHeapSize / 1024 / 1024).toFixed(2)} MB</p>
<p><strong>总内存:</strong> ${(memory.totalJSHeapSize / 1024 / 1024).toFixed(2)} MB</p>
<p><strong>内存限制:</strong> ${(memory.jsHeapSizeLimit / 1024 / 1024).toFixed(2)} MB</p>
<p><strong>使用率:</strong> ${(memory.usedJSHeapSize / memory.jsHeapSizeLimit * 100).toFixed(1)}%</p>
`;
drawMemoryChart();
} else {
memoryResults.innerHTML = '<p>当前浏览器不支持内存API</p>';
}
}
// 绘制内存图表
function drawMemoryChart() {
const canvas = document.getElementById('memoryChart');
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (performance.memory) {
const memory = performance.memory;
const used = memory.usedJSHeapSize / 1024 / 1024;
const total = memory.totalJSHeapSize / 1024 / 1024;
const limit = memory.jsHeapSizeLimit / 1024 / 1024;
// 绘制内存使用饼图
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const radius = 100;
// 已使用内存
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI * (used / limit));
ctx.fillStyle = '#FF6B6B';
ctx.fill();
// 剩余内存
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 2 * Math.PI * (used / limit), 2 * Math.PI);
ctx.fillStyle = '#4ECDC4';
ctx.fill();
// 标签
ctx.fillStyle = '#333';
ctx.font = '16px Arial';
ctx.textAlign = 'center';
ctx.fillText(`已使用: ${used.toFixed(1)}MB`, centerX, centerY - 20);
ctx.fillText(`剩余: ${(limit - used).toFixed(1)}MB`, centerX, centerY + 20);
}
}
// 实时性能监控
function startRealTimeMonitoring() {
if (realTimeMonitoring) return;
realTimeMonitoring = true;
const canvas = document.getElementById('realTimeChart');
const ctx = canvas.getContext('2d');
let frameCount = 0;
const dataPoints = [];
const maxDataPoints = 100;
monitoringInterval = setInterval(() => {
const start = performance.now();
// 执行一些计算任务
for (let i = 0; i < 10000; i++) {
Math.sqrt(i);
}
const end = performance.now();
const executionTime = end - start;
dataPoints.push(executionTime);
if (dataPoints.length > maxDataPoints) {
dataPoints.shift();
}
// 绘制实时图表
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (dataPoints.length > 1) {
const maxTime = Math.max(...dataPoints);
const scaleX = canvas.width / maxDataPoints;
const scaleY = canvas.height / (maxTime || 1);
ctx.beginPath();
ctx.strokeStyle = '#2196F3';
ctx.lineWidth = 2;
for (let i = 0; i < dataPoints.length; i++) {
const x = i * scaleX;
const y = canvas.height - (dataPoints[i] * scaleY);
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
ctx.stroke();
}
frameCount++;
}, 100);
}
// 停止实时监控
function stopRealTimeMonitoring() {
if (!realTimeMonitoring) return;
realTimeMonitoring = false;
if (monitoringInterval) {
clearInterval(monitoringInterval);
monitoringInterval = null;
}
}
// 垃圾收集测试
function runGCTest() {
const memoryResults = document.getElementById('memoryResults');
if (performance.memory) {
const initialMemory = performance.memory.usedJSHeapSize;
// 创建大量对象
const objects = [];
for (let i = 0; i < 100000; i++) {
objects.push({
id: i,
data: new Array(100).fill(Math.random()),
timestamp: Date.now()
});
}
const afterAllocation = performance.memory.usedJSHeapSize;
// 清理引用
objects.length = 0;
// 强制垃圾回收(如果可用)
if (window.gc) {
window.gc();
}
setTimeout(() => {
const afterGC = performance.memory.usedJSHeapSize;
memoryResults.innerHTML = `
<h3>垃圾收集测试</h3>
<p><strong>初始内存:</strong> ${(initialMemory / 1024 / 1024).toFixed(2)} MB</p>
<p><strong>分配后内存:</strong> ${(afterAllocation / 1024 / 1024).toFixed(2)} MB</p>
<p><strong>回收后内存:</strong> ${(afterGC / 1024 / 1024).toFixed(2)} MB</p>
<p><strong>分配的内存:</strong> ${((afterAllocation - initialMemory) / 1024 / 1024).toFixed(2)} MB</p>
<p><strong>回收的内存:</strong> ${((afterAllocation - afterGC) / 1024 / 1024).toFixed(2)} MB</p>
`;
}, 1000);
} else {
memoryResults.innerHTML = '<p>当前浏览器不支持内存API</p>';
}
}
// 页面加载时初始化
window.addEventListener('load', function() {
console.log('WebAssembly性能分析工具已加载');
// 检查WebAssembly支持
if (typeof WebAssembly === 'object') {
console.log('✅ WebAssembly支持已启用');
} else {
console.log('❌ WebAssembly不支持');
}
// 初始化内存分析
analyzeMemoryUsage();
});
// 页面卸载时清理
window.addEventListener('beforeunload', function() {
stopRealTimeMonitoring();
});
</script>
</body>
</html>WebAssembly的开发需要特定的工具链和编译器。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebAssembly开发工具</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1000px;
margin: 0 auto;
padding: 20px;
line-height: 1.6;
}
.tool-section {
background: #f9f9f9;
padding: 20px;
margin: 20px 0;
border-radius: 8px;
border-left: 4px solid #2196F3;
}
.code-example {
background: #2d2d2d;
color: #f8f8f2;
padding: 20px;
border-radius: 8px;
margin: 15px 0;
overflow-x: auto;
font-family: 'Courier New', monospace;
font-size: 14px;
}
.code-example .comment {
color: #75715e;
}
.code-example .keyword {
color: #f92672;
}
.code-example .string {
color: #e6db74;
}
.code-example .number {
color: #ae81ff;
}
.command-line {
background: #1e1e1e;
color: #00ff00;
padding: 15px;
border-radius: 8px;
margin: 15px 0;
font-family: 'Courier New', monospace;
font-size: 14px;
}
.step-container {
display: flex;
gap: 20px;
margin: 20px 0;
}
.step {
flex: 1;
background: white;
padding: 15px;
border-radius: 8px;
border: 1px solid #ddd;
text-align: center;
}
.step h4 {
margin: 0 0 10px 0;
color: #2196F3;
}
.workflow-diagram {
text-align: center;
margin: 30px 0;
}
.workflow-step {
display: inline-block;
background: #2196F3;
color: white;
padding: 10px 20px;
margin: 5px;
border-radius: 20px;
position: relative;
}
.workflow-step::after {
content: '→';
position: absolute;
right: -20px;
top: 50%;
transform: translateY(-50%);
color: #333;
}
.workflow-step:last-child::after {
display: none;
}
.tool-comparison {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
.tool-comparison th,
.tool-comparison td {
border: 1px solid #ddd;
padding: 12px;
text-align: left;
}
.tool-comparison th {
background-color: #f5f5f5;
}
.pros {
color: #4CAF50;
}
.cons {
color: #f44336;
}
</style>
</head>
<body>
<h1>WebAssembly开发工具和编译流程</h1>
<div class="tool-section">
<h2>开发工具概述</h2>
<p>WebAssembly开发需要特定的工具链来将高级语言代码编译为WASM格式。以下是主要的开发工具:</p>
<table class="tool-comparison">
<thead>
<tr>
<th>工具</th>
<th>支持语言</th>
<th>优点</th>
<th>缺点</th>
<th>适用场景</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Emscripten</strong></td>
<td>C/C++</td>
<td class="pros">成熟稳定、文档丰富、库支持好</td>
<td class="cons">体积较大、学习曲线陡峭</td>
<td>现有C/C++项目移植</td>
</tr>
<tr>
<td><strong>Rust</strong></td>
<td>Rust</td>
<td class="pros">内存安全、性能优异、工具链完整</td>
<td class="cons">语法复杂、学习成本高</td>
<td>新项目开发、系统级应用</td>
</tr>
<tr>
<td><strong>AssemblyScript</strong></td>
<td>TypeScript-like</td>
<td class="pros">语法简单、上手快、集成方便</td>
<td class="cons">生态较小、性能一般</td>
<td>快速原型、简单应用</td>
</tr>
<tr>
<td><strong>TinyGo</strong></td>
<td>Go</td>
<td class="pros">语法简洁、编译快速</td>
<td class="cons">功能受限、标准库不完整</td>
<td>Go开发者、小型应用</td>
</tr>
</tbody>
</table>
</div>
<div class="tool-section">
<h2>Emscripten开发流程</h2>
<p>Emscripten是最成熟的WebAssembly编译工具,可以将C/C++代码编译为WebAssembly。</p>
<div class="workflow-diagram">
<div class="workflow-step">C/C++源码</div>
<div class="workflow-step">预处理</div>
<div class="workflow-step">编译</div>
<div class="workflow-step">链接</div>
<div class="workflow-step">WASM输出</div>
</div>
<h3>1. 安装Emscripten</h3>
<div class="command-line">
# 克隆Emscripten仓库
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
# 安装最新版本
./emsdk install latest
./emsdk activate latest
# 设置环境变量
source ./emsdk_env.sh
</div>
<h3>2. 编写C代码</h3>
<div class="code-example">
<span class="comment">// math.c</span>
<span class="keyword">#include</span> <span class="string"><emscripten/emscripten.h></span>
<span class="comment">// 导出函数给JavaScript使用</span>
<span class="keyword">EMSCRIPTEN_KEEPALIVE</span>
<span class="keyword">int</span> add(<span class="keyword">int</span> a, <span class="keyword">int</span> b) {
<span class="keyword">return</span> a + b;
}
<span class="keyword">EMSCRIPTEN_KEEPALIVE</span>
<span class="keyword">double</span> calculate_pi(<span class="keyword">int</span> iterations) {
<span class="keyword">double</span> pi = <span class="number">0.0</span>;
<span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < iterations; i++) {
pi += (i % <span class="number">2</span> == <span class="number">0</span> ? <span class="number">1.0</span> : <span class="number">-1.0</span>) / (<span class="number">2</span> * i + <span class="number">1</span>);
}
<span class="keyword">return</span> pi * <span class="number">4.0</span>;
}
<span class="keyword">EMSCRIPTEN_KEEPALIVE</span>
<span class="keyword">void</span> process_array(<span class="keyword">int</span>* arr, <span class="keyword">int</span> size) {
<span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < size; i++) {
arr[i] = arr[i] * arr[i];
}
}
</div>
<h3>3. 编译为WebAssembly</h3>
<div class="command-line">
# 基本编译
emcc math.c -o math.js -s WASM=1
# 优化编译
emcc math.c -o math.js -s WASM=1 -O3 -s EXPORTED_FUNCTIONS="['_add', '_calculate_pi', '_process_array']"
# 生成独立的WASM文件
emcc math.c -o math.wasm -s STANDALONE_WASM=1
</div>
<h3>4. 在JavaScript中使用</h3>
<div class="code-example">
<span class="comment">// 加载Emscripten生成的模块</span>
<span class="keyword">const</span> Module = <span class="keyword">require</span>(<span class="string">'./math.js'</span>);
Module.onRuntimeInitialized = <span class="keyword">function</span>() {
<span class="comment">// 调用C函数</span>
<span class="keyword">const</span> result = Module._add(<span class="number">5</span>, <span class="number">3</span>);
console.log(<span class="string">'Addition result:'</span>, result);
<span class="comment">// 计算π值</span>
<span class="keyword">const</span> pi = Module._calculate_pi(<span class="number">1000000</span>);
console.log(<span class="string">'Calculated π:'</span>, pi);
<span class="comment">// 处理数组</span>
<span class="keyword">const</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>];
<span class="keyword">const</span> ptr = Module._malloc(arr.length * <span class="number">4</span>);
Module.HEAP32.set(arr, ptr / <span class="number">4</span>);
Module._process_array(ptr, arr.length);
<span class="keyword">const</span> result_arr = Module.HEAP32.slice(ptr / <span class="number">4</span>, ptr / <span class="number">4</span> + arr.length);
console.log(<span class="string">'Processed array:'</span>, result_arr);
Module._free(ptr);
};
</div>
</div>
<div class="tool-section">
<h2>Rust开发流程</h2>
<p>Rust提供了优秀的WebAssembly支持,具有内存安全和高性能的特点。</p>
<h3>1. 安装Rust和wasm-pack</h3>
<div class="command-line">
# 安装Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 安装wasm-pack
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
# 添加WebAssembly目标
rustup target add wasm32-unknown-unknown
</div>
<h3>2. 创建Rust项目</h3>
<div class="command-line">
# 创建新项目
cargo new --lib wasm-math
cd wasm-math
</div>
<h3>3. 配置Cargo.toml</h3>
<div class="code-example">
[package]
name = <span class="string">"wasm-math"</span>
version = <span class="string">"0.1.0"</span>
edition = <span class="string">"2021"</span>
[lib]
crate-type = [<span class="string">"cdylib"</span>]
[dependencies]
wasm-bindgen = <span class="string">"0.2"</span>
js-sys = <span class="string">"0.3"</span>
web-sys = <span class="string">"0.3"</span>
[dependencies.web-sys]
version = <span class="string">"0.3"</span>
features = [
<span class="string">"console"</span>,
<span class="string">"Performance"</span>,
<span class="string">"Window"</span>,
]
</div>
<h3>4. 编写Rust代码</h3>
<div class="code-example">
<span class="comment">// src/lib.rs</span>
<span class="keyword">use</span> wasm_bindgen::prelude::*;
<span class="keyword">use</span> web_sys::console;
<span class="comment">// 导入JavaScript函数</span>
<span class="keyword">#[wasm_bindgen]</span>
<span class="keyword">extern</span> <span class="string">"C"</span> {
<span class="keyword">fn</span> alert(s: &<span class="keyword">str</span>);
}
<span class="comment">// 定义宏用于日志</span>
<span class="keyword">macro_rules!</span> log {
( $( $t:tt )* ) => {
console::log_1(&format!( $( $t )* ).into());
}
}
<span class="comment">// 导出函数给JavaScript</span>
<span class="keyword">#[wasm_bindgen]</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> add(a: <span class="keyword">i32</span>, b: <span class="keyword">i32</span>) -> <span class="keyword">i32</span> {
a + b
}
<span class="keyword">#[wasm_bindgen]</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> fibonacci(n: <span class="keyword">u32</span>) -> <span class="keyword">u32</span> {
<span class="keyword">match</span> n {
<span class="number">0</span> => <span class="number">0</span>,
<span class="number">1</span> => <span class="number">1</span>,
_ => fibonacci(n - <span class="number">1</span>) + fibonacci(n - <span class="number">2</span>),
}
}
<span class="keyword">#[wasm_bindgen]</span>
<span class="keyword">pub</span> <span class="keyword">struct</span> Calculator {
value: <span class="keyword">f64</span>,
}
<span class="keyword">#[wasm_bindgen]</span>
<span class="keyword">impl</span> Calculator {
<span class="keyword">#[wasm_bindgen(constructor)]</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> new() -> Calculator {
Calculator { value: <span class="number">0.0</span> }
}
<span class="keyword">#[wasm_bindgen(getter)]</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> value(&<span class="keyword">self</span>) -> <span class="keyword">f64</span> {
<span class="keyword">self</span>.value
}
<span class="keyword">#[wasm_bindgen]</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> add(&<span class="keyword">mut</span> <span class="keyword">self</span>, value: <span class="keyword">f64</span>) -> <span class="keyword">f64</span> {
<span class="keyword">self</span>.value += value;
<span class="keyword">self</span>.value
}
<span class="keyword">#[wasm_bindgen]</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> multiply(&<span class="keyword">mut</span> <span class="keyword">self</span>, value: <span class="keyword">f64</span>) -> <span class="keyword">f64</span> {
<span class="keyword">self</span>.value *= value;
<span class="keyword">self</span>.value
}
}
<span class="comment">// 页面加载时调用</span>
<span class="keyword">#[wasm_bindgen(start)]</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> main() {
log!(<span class="string">"WebAssembly module loaded from Rust!"</span>);
}
</div>
<h3>5. 构建WebAssembly</h3>
<div class="command-line">
# 构建WebAssembly包
wasm-pack build --target web
# 构建为npm包
wasm-pack build --target nodejs
</div>
<h3>6. 在JavaScript中使用</h3>
<div class="code-example">
<span class="keyword">import</span> init, { add, fibonacci, Calculator } <span class="keyword">from</span> <span class="string">'./pkg/wasm_math.js'</span>;
<span class="keyword">async</span> <span class="keyword">function</span> run() {
<span class="comment">// 初始化WebAssembly模块</span>
<span class="keyword">await</span> init();
<span class="comment">// 使用导出的函数</span>
console.log(<span class="string">'Add:'</span>, add(<span class="number">5</span>, <span class="number">3</span>));
console.log(<span class="string">'Fibonacci:'</span>, fibonacci(<span class="number">10</span>));
<span class="comment">// 使用导出的类</span>
<span class="keyword">const</span> calc = <span class="keyword">new</span> Calculator();
calc.add(<span class="number">10</span>);
calc.multiply(<span class="number">2</span>);
console.log(<span class="string">'Calculator result:'</span>, calc.value);
}
run();
</div>
</div>
<div class="tool-section">
<h2>AssemblyScript开发流程</h2>
<p>AssemblyScript使用类似TypeScript的语法,是最容易上手的WebAssembly开发语言。</p>
<h3>1. 安装AssemblyScript</h3>
<div class="command-line">
# 创建新项目
mkdir assemblyscript-math
cd assemblyscript-math
npm init -y
# 安装AssemblyScript
npm install --save-dev assemblyscript
npx asinit .
</div>
<h3>2. 编写AssemblyScript代码</h3>
<div class="code-example">
<span class="comment">// assembly/index.ts</span>
<span class="keyword">export</span> <span class="keyword">function</span> add(a: <span class="keyword">i32</span>, b: <span class="keyword">i32</span>): <span class="keyword">i32</span> {
<span class="keyword">return</span> a + b;
}
<span class="keyword">export</span> <span class="keyword">function</span> multiply(a: <span class="keyword">f64</span>, b: <span class="keyword">f64</span>): <span class="keyword">f64</span> {
<span class="keyword">return</span> a * b;
}
<span class="keyword">export</span> <span class="keyword">function</span> fibonacci(n: <span class="keyword">i32</span>): <span class="keyword">i32</span> {
<span class="keyword">if</span> (n < <span class="number">2</span>) <span class="keyword">return</span> n;
<span class="keyword">return</span> fibonacci(n - <span class="number">1</span>) + fibonacci(n - <span class="number">2</span>);
}
<span class="comment">// 字符串处理</span>
<span class="keyword">export</span> <span class="keyword">function</span> reverse(str: <span class="keyword">string</span>): <span class="keyword">string</span> {
<span class="keyword">let</span> result = <span class="string">""</span>;
<span class="keyword">for</span> (<span class="keyword">let</span> i = str.length - <span class="number">1</span>; i >= <span class="number">0</span>; i--) {
result += str.charAt(i);
}
<span class="keyword">return</span> result;
}
<span class="comment">// 数组处理</span>
<span class="keyword">export</span> <span class="keyword">function</span> sum(arr: <span class="keyword">Int32Array</span>): <span class="keyword">i32</span> {
<span class="keyword">let</span> total = <span class="number">0</span>;
<span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i < arr.length; i++) {
total += arr[i];
}
<span class="keyword">return</span> total;
}
</div>
<h3>3. 编译和使用</h3>
<div class="command-line">
# 编译为WebAssembly
npm run asbuild
# 启动开发服务器
npm run serve
</div>
<div class="code-example">
<span class="comment">// JavaScript使用示例</span>
<span class="keyword">import</span> { add, multiply, fibonacci, reverse, sum } <span class="keyword">from</span> <span class="string">"./build/release.js"</span>;
<span class="comment">// 使用导出的函数</span>
console.log(<span class="string">'Add:'</span>, add(<span class="number">5</span>, <span class="number">3</span>));
console.log(<span class="string">'Multiply:'</span>, multiply(<span class="number">2.5</span>, <span class="number">4.0</span>));
console.log(<span class="string">'Fibonacci:'</span>, fibonacci(<span class="number">10</span>));
console.log(<span class="string">'Reverse:'</span>, reverse(<span class="string">"Hello"</span>));
<span class="comment">// 处理数组</span>
<span class="keyword">const</span> arr = <span class="keyword">new</span> Int32Array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]);
console.log(<span class="string">'Sum:'</span>, sum(arr));
</div>
</div>
<div class="tool-section">
<h2>性能优化技巧</h2>
<div class="step-container">
<div class="step">
<h4>编译优化</h4>
<p>使用-O3优化级别,启用链接时优化(LTO)</p>
</div>
<div class="step">
<h4>内存管理</h4>
<p>合理使用内存,避免频繁的内存分配和释放</p>
</div>
<div class="step">
<h4>函数内联</h4>
<p>使用内联函数减少函数调用开销</p>
</div>
<div class="step">
<h4>数据类型</h4>
<p>选择合适的数据类型,避免不必要的类型转换</p>
</div>
</div>
<h3>编译器优化选项</h3>
<div class="command-line">
# Emscripten优化
emcc -O3 -s ALLOW_MEMORY_GROWTH=1 -s INITIAL_MEMORY=16MB
# Rust优化
cargo build --release --target wasm32-unknown-unknown
# AssemblyScript优化
asc assembly/index.ts --optimize --shrinkLevel 2
</div>
<h3>运行时优化</h3>
<div class="code-example">
<span class="comment">// 预加载WebAssembly模块</span>
<span class="keyword">const</span> wasmPromise = WebAssembly.instantiateStreaming(fetch(<span class="string">'module.wasm'</span>));
<span class="comment">// 使用SharedArrayBuffer提高性能</span>
<span class="keyword">const</span> sharedBuffer = <span class="keyword">new</span> SharedArrayBuffer(<span class="number">1024</span>);
<span class="keyword">const</span> sharedArray = <span class="keyword">new</span> Int32Array(sharedBuffer);
<span class="comment">// 批量处理数据</span>
<span class="keyword">function</span> processInBatches(data, batchSize = <span class="number">1000</span>) {
<span class="keyword">const</span> results = [];
<span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i < data.length; i += batchSize) {
<span class="keyword">const</span> batch = data.slice(i, i + batchSize);
results.push(...processData(batch));
}
<span class="keyword">return</span> results;
}
</div>
</div>
<div class="tool-section">
<h2>调试和测试</h2>
<h3>调试技巧</h3>
<div class="code-example">
<span class="comment">// 使用浏览器开发者工具调试</span>
<span class="keyword">console</span>.log(<span class="string">'Debug info:'</span>, wasmModule.exports);
<span class="comment">// 性能分析</span>
<span class="keyword">const</span> start = performance.now();
wasmModule.exports.complexCalculation();
<span class="keyword">const</span> end = performance.now();
<span class="keyword">console</span>.log(<span class="string">'Execution time:'</span>, end - start);
<span class="comment">// 内存使用监控</span>
<span class="keyword">if</span> (performance.memory) {
<span class="keyword">console</span>.log(<span class="string">'Memory usage:'</span>, performance.memory.usedJSHeapSize);
}
</div>
<h3>单元测试</h3>
<div class="code-example">
<span class="comment">// Jest测试示例</span>
<span class="keyword">import</span> { add, multiply } <span class="keyword">from</span> <span class="string">'./wasm-module'</span>;
describe(<span class="string">'WASM Math Functions'</span>, () => {
test(<span class="string">'addition works correctly'</span>, () => {
expect(add(<span class="number">2</span>, <span class="number">3</span>)).toBe(<span class="number">5</span>);
expect(add(-<span class="number">1</span>, <span class="number">1</span>)).toBe(<span class="number">0</span>);
});
test(<span class="string">'multiplication works correctly'</span>, () => {
expect(multiply(<span class="number">3</span>, <span class="number">4</span>)).toBe(<span class="number">12</span>);
expect(multiply(-<span class="number">2</span>, <span class="number">5</span>)).toBe(-<span class="number">10</span>);
});
});
</div>
</div>
</body>
</html>A: WebAssembly适合计算密集型任务,如图像处理、音视频编解码、游戏引擎、科学计算等需要高性能的场景。
A: 不能。WebAssembly专注于计算性能,而JavaScript更适合DOM操作、事件处理等Web交互。两者互补使用效果最佳。
A: 根据项目需求选择:C/C++适合移植现有代码,Rust适合新项目追求性能,AssemblyScript适合快速原型开发。
A: 现代浏览器都支持WebAssembly,包括Chrome、Firefox、Safari、Edge等,移动端支持也很好。
A: 这取决于代码复杂度和优化程度,简单的数学函数可能只有几KB,复杂的应用可能有几MB。通过优化可以显著减小文件大小。
下一节预览:下一节我们将学习新兴Web技术,重点介绍WebXR、WebGL等前沿技术的应用和发展趋势。