JavaScript系列(32)-- WebAssembly集成详解
JavaScript WebAssembly集成详解 🚀
今天,让我们深入了解JavaScript与WebAssembly的集成,这是一项能够显著提升Web应用性能的关键技术。
WebAssembly基础概念 🌟
💡 小知识:WebAssembly(简称Wasm)是一种低级的类汇编语言,它具有紧凑的二进制格式,能够以接近原生的速度运行。它被设计为可以和JavaScript一起协同工作,为Web应用提供高性能计算能力。
基本集成实现 📊
// 1. 加载WebAssembly模块
async function loadWasmModule() {try {const response = await fetch('example.wasm');const bytes = await response.arrayBuffer();const wasmModule = await WebAssembly.instantiate(bytes);return wasmModule.instance.exports;} catch (error) {console.error('Failed to load WASM module:', error);throw error;}
}// 2. 内存管理
class WasmMemoryManager {constructor(initialPages = 1) {this.memory = new WebAssembly.Memory({ initial: initialPages,maximum: 100 });this.buffer = new Uint8Array(this.memory.buffer);}writeString(str, offset) {const encoder = new TextEncoder();const bytes = encoder.encode(str);this.buffer.set(bytes, offset);return bytes.length;}readString(offset, length) {const decoder = new TextDecoder();return decoder.decode(this.buffer.slice(offset, offset + length));}
}// 3. 基本类型转换
class WasmTypeConverter {static toWasmInt(num) {return num | 0; // 转换为32位整数}static toWasmFloat(num) {return Math.fround(num); // 转换为32位浮点数}static fromWasmInt(num) {return Number(num);}
}
高级集成模式 🚀
// 1. 异步加载器
class WasmLoader {constructor(wasmUrl) {this.wasmUrl = wasmUrl;this.modulePromise = null;}async load() {if (!this.modulePromise) {this.modulePromise = WebAssembly.instantiateStreaming(fetch(this.wasmUrl));}const { instance } = await this.modulePromise;return instance.exports;}async loadWithImports(imports) {const response = await fetch(this.wasmUrl);const bytes = await response.arrayBuffer();return WebAssembly.instantiate(bytes, imports);}
}// 2. 共享内存通信
class SharedMemoryBridge {constructor(size = 1024 * 1024) { // 1MBthis.sharedMemory = new SharedArrayBuffer(size);this.view = new Int32Array(this.sharedMemory);}write(index, value) {Atomics.store(this.view, index, value);}read(index) {return Atomics.load(this.view, index);}waitFor(index, expectedValue) {Atomics.wait(this.view, index, expectedValue);}notify(index) {Atomics.notify(this.view, index, 1);}
}// 3. 性能监控包装器
class WasmPerformanceWrapper {constructor(wasmExports) {this.exports = wasmExports;this.metrics = new Map();}wrap(functionName) {const original = this.exports[functionName];const metrics = this.metrics;this.exports[functionName] = function(...args) {const start = performance.now();try {return original.apply(this, args);} finally {const duration = performance.now() - start;const current = metrics.get(functionName) || [];current.push(duration);metrics.set(functionName, current);}};}getMetrics(functionName) {const times = this.metrics.get(functionName) || [];return {calls: times.length,averageTime: times.reduce((a, b) => a + b, 0) / times.length,maxTime: Math.max(...times),minTime: Math.min(...times)};}
}
实际应用场景 💼
// 1. 图像处理应用
class WasmImageProcessor {constructor(wasmModule) {this.wasm = wasmModule;this.memory = new WasmMemoryManager(10); // 10 pages}async processImage(imageData) {const ptr = this.wasm.allocateMemory(imageData.length);const buffer = new Uint8ClampedArray(this.memory.memory.buffer,ptr,imageData.length);buffer.set(imageData);await this.wasm.processImage(ptr, imageData.width, imageData.height);return new ImageData(buffer,imageData.width,imageData.height);}
}// 2. 密码学应用
class WasmCrypto {constructor(wasmModule) {this.wasm = wasmModule;}async hash(data) {const encoder = new TextEncoder();const input = encoder.encode(data);const inputPtr = this.wasm.allocate(input.length);new Uint8Array(this.wasm.memory.buffer).set(input, inputPtr);const hashPtr = await this.wasm.computeHash(inputPtr, input.length);const hashLength = 32; // SHA-256const hashArray = new Uint8Array(this.wasm.memory.buffer,hashPtr,hashLength);return Array.from(hashArray).map(b => b.toString(16).padStart(2, '0')).join('');}
}// 3. 数学计算应用
class WasmMath {constructor(wasmModule) {this.wasm = wasmModule;}async computeMatrix(matrix1, matrix2) {const rows1 = matrix1.length;const cols1 = matrix1[0].length;const cols2 = matrix2[0].length;const ptr1 = this.wasm.allocateMatrix(rows1 * cols1);const ptr2 = this.wasm.allocateMatrix(cols1 * cols2);// 转换并复制数据到WASM内存this.copyMatrixToWasm(matrix1, ptr1);this.copyMatrixToWasm(matrix2, ptr2);const resultPtr = await this.wasm.multiplyMatrices(ptr1, ptr2, rows1, cols1, cols2);return this.readMatrixFromWasm(resultPtr, rows1, cols2);}
}
性能优化技巧 ⚡
// 1. 内存池优化
class WasmMemoryPool {constructor(initialSize = 1024 * 1024) {this.memory = new WebAssembly.Memory({initial: initialSize / 65536, // 每页64KBmaximum: 100});this.allocations = new Map();this.freeList = [{offset: 0,size: initialSize}];}allocate(size) {// 查找最佳匹配的空闲块const blockIndex = this.freeList.findIndex(block => block.size >= size);if (blockIndex === -1) {throw new Error('Out of memory');}const block = this.freeList[blockIndex];const allocation = {offset: block.offset,size: size};// 更新空闲列表if (block.size === size) {this.freeList.splice(blockIndex, 1);} else {block.offset += size;block.size -= size;}this.allocations.set(allocation.offset, allocation);return allocation.offset;}free(offset) {const allocation = this.allocations.get(offset);if (!allocation) return;this.allocations.delete(offset);this.freeList.push(allocation);this.mergeFreeBlocks();}mergeFreeBlocks() {this.freeList.sort((a, b) => a.offset - b.offset);for (let i = 0; i < this.freeList.length - 1; i++) {const current = this.freeList[i];const next = this.freeList[i + 1];if (current.offset + current.size === next.offset) {current.size += next.size;this.freeList.splice(i + 1, 1);i--;}}}
}// 2. 并行计算优化
class WasmParallelCompute {constructor(wasmModule, threadCount = navigator.hardwareConcurrency) {this.wasm = wasmModule;this.threadCount = threadCount;this.workers = [];this.initWorkers();}async initWorkers() {const sharedMemory = new SharedArrayBuffer(1024 * 1024);for (let i = 0; i < this.threadCount; i++) {const worker = new Worker('wasm-worker.js');worker.postMessage({ type: 'init',memory: sharedMemory,wasmModule: this.wasm});this.workers.push(worker);}}async computeParallel(data) {const chunkSize = Math.ceil(data.length / this.threadCount);const promises = this.workers.map((worker, index) => {const start = index * chunkSize;const end = Math.min(start + chunkSize, data.length);const chunk = data.slice(start, end);return new Promise(resolve => {worker.onmessage = e => resolve(e.data);worker.postMessage({ type: 'compute',data: chunk});});});const results = await Promise.all(promises);return this.mergeResults(results);}
}// 3. 缓存优化
class WasmCache {constructor(maxSize = 100) {this.cache = new Map();this.maxSize = maxSize;}set(key, value) {if (this.cache.size >= this.maxSize) {const oldestKey = this.cache.keys().next().value;this.cache.delete(oldestKey);}this.cache.set(key, {value,timestamp: Date.now()});}get(key) {const entry = this.cache.get(key);if (entry) {entry.timestamp = Date.now();return entry.value;}return null;}cleanup(maxAge = 3600000) { // 1小时const now = Date.now();for (const [key, entry] of this.cache.entries()) {if (now - entry.timestamp > maxAge) {this.cache.delete(key);}}}
}
最佳实践建议 💡
- 模块化设计
// 1. 模块化WASM加载器
class ModularWasmLoader {static async load(modules) {const instances = new Map();for (const [name, url] of Object.entries(modules)) {const instance = await loadWasmModule(url);instances.set(name, instance);}return {get(moduleName) {return instances.get(moduleName);},call(moduleName, functionName, ...args) {const module = instances.get(moduleName);if (!module) {throw new Error(`Module ${moduleName} not found`);}return module.exports[functionName](...args);}};}
}// 2. 错误处理
class WasmErrorHandler {static wrap(promise) {return promise.catch(error => {if (error instanceof WebAssembly.RuntimeError) {console.error('WASM runtime error:', error);throw new Error('WASM execution failed');}if (error instanceof WebAssembly.LinkError) {console.error('WASM linking error:', error);throw new Error('WASM module linking failed');}throw error;});}
}// 3. 资源管理
class WasmResourceManager {constructor() {this.resources = new Map();}register(resource) {this.resources.set(resource.id, resource);}async cleanup() {for (const resource of this.resources.values()) {await resource.dispose();}this.resources.clear();}
}
结语 📝
WebAssembly为JavaScript应用带来了前所未有的性能提升可能。通过本文,我们学习了:
- WebAssembly的基本概念和集成方法
- 高级集成模式和内存管理
- 实际应用场景和示例
- 性能优化技巧
- 最佳实践和设计模式
💡 学习建议:在使用WebAssembly时,要注意平衡开发复杂度和性能收益。不是所有场景都适合使用WebAssembly,要根据实际需求选择合适的解决方案。
如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇
终身学习,共同成长。
咱们下一期见
💻
相关文章:
JavaScript系列(32)-- WebAssembly集成详解
JavaScript WebAssembly集成详解 🚀 今天,让我们深入了解JavaScript与WebAssembly的集成,这是一项能够显著提升Web应用性能的关键技术。 WebAssembly基础概念 🌟 💡 小知识:WebAssembly(简称W…...
wps数据分析000002
目录 一、快速定位技巧 二、快速选中技巧 全选 选中部分区域 选中部分区域(升级版) 三、快速移动技巧 四、快速录入技巧 五、总结 一、快速定位技巧 ctrl→(上下左右)快速定位光标对准单元格的上下部分双击名称单元格中…...
无降智o1 pro——一次特别的ChatGPT专业模式探索
这段时间和朋友们交流 ChatGPT 的使用心得,大家都提到一个很“神秘”的服务:它基于 O1 Pro 模型,能够在对话里一直保持相对高水平的理解和回复,不会突然变得“降智”。同时,整体使用还做了免折腾的网络设置——简单一点…...
前端:前端开发任务分解 / 开发清单
一、背景 前端开发过程中,好多任务同时开发,或者一个大的任务分解为若干个子任务进行开发,分解出去的很多内容容易记不清楚 / 不易过程管理,所以记录表格如下,方便开发同事,也辅助掌握整体开发情况。 二、…...
【Django自学】Django入门:如何使用django开发一个web项目(非常详细)
测试机器:windows11 x64 python版本:3.11 一、安装Django 安装步骤非常简单,使用pip安装就行 pip install django安装完成之后,python的 Scripts 文件夹下,会多一个 django-admin.exe (管理创建django项目的工具)。…...
面试经验分享-回忆版某小公司
说说你项目中数据仓库是怎么分层的,为什么要分层? 首先是ODS层,连接数据源和数据仓库,数据会进行简单的ETL操作,数据来源通常是业务数据库,用户日志文件或者来自消息队列的数据等 中间是核心的数据仓库层&a…...
WebSocket——推送方案选型
一、前言:为何需要服务端主动推送? 在现代应用中,很多功能都依赖于“消息推送”。比如: 小红点提醒:我们经常在手机应用里看到的一个小红点提示,表示有新的消息或任务需要我们关注。新消息提醒࿱…...
山石防火墙命令行配置示例
现网1台山石SG6000防火墙,配置都可以通过GUI实现。 但有一些配置在命令行下配置效率更高,比如在1个已有策略中添加1个host或端口。 下面的双引号可以不加 1 创建服务 1.1 单个端口 service "tcp-901"tcp dst-port 901 1.2 端口范围 servi…...
LLM - 大模型 ScallingLaws 的 C=6ND 公式推导 教程(1)
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/145185794 Scaling Laws (缩放法则) 是大模型领域中,用于描述 模型性能(Loss) 与 模型规模N、数据量D、计算资源C 之间关系的经验规律…...
Leetcode 983. 最低票价 动态规划
原题链接:Leetcode 983. 最低票价 class Solution { public:int mincostTickets(vector<int>& days, vector<int>& costs) {int n days.size();int last days[n - 1];int dp[last 1];map<int, int> mp;for (auto x : days)mp[x] 1;dp…...
Kafka——两种集群搭建详解 k8s
1、简介 Kafka是一个能够支持高并发以及流式消息处理的消息中间件,并且Kafka天生就是支持集群的,今天就主要来介绍一下如何搭建Kafka集群。 Kafka目前支持使用Zookeeper模式搭建集群以及KRaft模式(即无Zookeeper)模式这两种模式搭…...
springboot使用websocket
文章目录 一、概述1、简介 二、 使用1、引包2、配置处理器3、前端测试 一、概述 1、简介 简介略,附上官方文档,spring5和spring6的官方文档内容大致是一样的: https://docs.spring.io/spring-framework/docs/5.2.25.RELEASE/spring-framewo…...
Redis的安装和配置、基本命令
一、实验目的 本实验旨在帮助学生熟悉Redis的安装、配置和基本使用,包括启动Redis服务、使用命令行客户端进行操作、配置Redis、进行多数据库操作以及掌握键值相关和服务器相关的命令。 二、实验环境准备 1. JAVA环境准备:确保Java Development Kit …...
Rnote:Star 8.6k,github上的宝藏项目,手绘与手写画图笔记,用它画图做笔记超丝滑,值得尝试!
嗨,大家好,我是小华同学,关注我们获得“最新、最全、最优质”开源项目和高效工作学习方法 Rnote是一款开源的基于矢量的绘图应用,专为学生、教师以及绘图板用户设计。它支持草图绘制、手写笔记以及对文档和图片进行注释。Rnote提供…...
python如何解析word文件格式(.docx)
python如何解析word文件格式(.docx) .docx文件遵从开源的“Office Open XML标准”,这意味着我们能用python的文本操作对它进行操作(实际上PPT和Excel也是)。而且这并不是重复造轮子,因为市面上操作.docx的…...
「刘一哥GIS」系列专栏《GRASS GIS零基础入门实验教程(配套案例数据)》专栏上线了
「刘一哥GIS」系列专栏《GRASS GIS零基础入门实验教程》全新上线了,欢迎广大GISer朋友关注,一起探索GIS奥秘,分享GIS价值! 本专栏以实战案例的形式,深入浅出地介绍了GRASS GIS的基本使用方法,用一个个实例讲…...
使用nginx搭建通用的图片代理服务器,支持http/https/重定向式图片地址
从http切换至https 许多不同ip的图片地址需要统一进行代理 部分图片地址是重定向地址 nginx配置 主站地址:https://192.168.123.100/ 主站nginx配置 server {listen 443 ssl;server_name localhost;#ssl证书ssl_certificate ../ssl/ca.crt; #私钥文件ssl_ce…...
零基础构建最简单的 Tauri2.0 桌面项目 Star 88.4k!!!
目录 预安装环境 安装nodejs windows下安装 linux下安装 nodejs常遇问题 安装C环境 介绍 下载 安装 安装Rust语言 Tauri官网 安装 vscode 安装 rust 插件 安装 Tauri 插件 运行成果 预安装环境 安装nodejs windows下安装 NodeJs_安装及下载_哔哩哔哩_bilibi…...
智能科技与共情能力加持,哈曼重新定义驾乘体验
2025年1月6日,拉斯维加斯,2025年国际消费电子展——想象一下,当您步入一辆汽车,它不仅能响应您的指令,更能理解您的需求、适应您的偏好,并为您创造一个独特且专属的交互环境。作为汽车科技领域的知名企业和…...
猫贫血吃什么能快速补血?
各位铲屎官们,看到自家猫咪无精打采、小脸苍白,是不是特别心疼?贫血可是猫咪健康的大敌,今天就来给大家支支招,哪些食物和方法能让猫咪快速补血,恢复活力! 一、红肉及内脏类 红肉是补血的“主力…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
