初探webAssembly | 京东物流技术团队

1 WebAssembly是什么?

一种运行在现代网络浏览器中的新型代码,并且提供新的性能特性和效果

W3C WebAssembly Community Group开发的一项网络标准,对于浏览器而言,WebAssembly 提供了一条途径,让各种语言编写的代码以接近原生的速度在 Web 中运行。在这种情况下,以前无法以此方式运行的客户端软件等都将可以运行在 Web 中。

WebAssembly 设计之初就决定和 JavaScript 一起协同运行——通过JavaScript 中的 WebAssembly API,可以把 WebAssembly 模块加载到一个 JavaScript 应用中并且在两者之间互相调用。这样可以在同一个应用中使用 WebAssembly 的高性能及 JavaScript 的高灵活性。

2 为什么需要WebAssembly?

众所周知JavaScript是解释型语言,相比于编译型语言需要在运行时转换,所以解释型语言的执行速度要慢于编译型语言。

编译型语言和解释型语言代码执行的具体流程如下:

因为解释型语言每次执行都需要把源码转换一次才能执行,而转换过程非常耗费时间和性能,也就导致在JavaScript背景下,web无法执行一些高性能应用,如图片剪辑、视频剪辑、3D游戏等。

根据MDN的定义,WebAssembly是一种运行在现代网络浏览器中的新型代码,并且提供新的性能特性和效果。可以在现代的网络浏览器中运行 - 它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如C / C ++等语言提供一个编译目标,以便它们可以在Web上运行。它也被设计为可以与JavaScript共存,允许两者一起工作。

3 WebAssembly的工作原理

WebAssembly不被解释,而是由开发者提前编译为WebAssembly二进制格式,如下图所示。由于变量类型都是预知的,因此浏览器加载WebAssembly文件时,JavaScript引擎无须监测代码。它可以简单地将这段代码的二进制格式编译为机器码。

如果将每种编程语言都直接编译为机器码的各个版本,那么效率会很低。编译器中称为前端的部分会将所编写的代码编译为一种中间表示(intermediate representation,IR)。创建好IR代码后,编译器的后端部分会接收IR代码,对其进行优化,然后将其转换为所需要的机器码。

由于浏览器可以在若干不同的处理器(比如桌面计算机、智能手机和平板设备)上运行,因此为每个可能的处理器发布一个WebAssembly代码的编译后版本会非常繁复。替代方法即取得IR代码,并通过一个专门的编译器来运行,这个编译器将IR代码转换为一种专用字节码并放入后缀为.wasm的文件中。此时wasm文件中的字节码还不是机器码,它只是支持WebAssembly的浏览器能够理解的一组虚拟指令。当加载到支持WebAssembly的浏览器中时,浏览器会验证这个文件的合法性,然后这些字节码会继续编译为浏览器所运行的设备上的机器码。如下图

WebAssembly被设计为JavaScript的一个组件,不是它的替代品。虽然有些开发者试图只用WebAssembly来创建整个网站,但这不是普遍情况。一般情况JavaScript仍然是更好的选择。

4 WebAssembly模块内部

模块中不同段的含义说明:

编译器负责生成WebAssembly模块的段,并将它们按照适当顺序放置。

所有的段都是可选的,因此可能存在空模块。

如果指定了已知段,那么它们只能出现一次并且要按照特定顺序出现。

自定义段可以放置在已知段之前、之间或之后,用于指定不适用已知段的数据。

5 哪些语言可用来创建WebAssembly模块?

现在WebAssembly的最小可行性版本(Minimum Viable Product,MVP)还没有垃圾回收(garbage collection,GC),他限制了一些语言的使用。GC作为一种后MVP功能正在开发中,实现之前,有几种语言正在试验WebAssembly支持,方式是将自己的VM编译到WebAssembly,或者在某些情况下将自己的垃圾回收器包含进去。

以下语言正在试验或已经完成WebAssembly支持:

  • C和C++
  • Rust正致力于成为WebAssembly的首选编程语言。
  • AssemblyScript是一种新编译器,它用来将TypeScript转换为WebAssembly。
  • TeaVM是一个将Java转译到JavaScript的工具,现在也可以生成WebAssembly了。
  • Go 1.11为WebAssembly增加了一个试验性项目,其编译后的WebAssembly模块包含一个垃圾回收器。
  • Pyodide是Python的一个项目,其中包含了Python科学栈的核心包:Numpy、Pandas和matplotlib。
  • Blazor是微软的实验性项目,用于将C#引入WebAssembly。

更多列表关注github: WebAssembly支持列表

相关案例:

TeaVM:它可以将 JVM 字节码翻译成 JavaScript 和 WebAssembly

我们有一段时间后端开始做一些前端开发,但是结果有时并不尽如人意,关键就在于我们的后端开发人员对前端无论是框架还是语法还是规范,都不是非常了解。这是在所难免的,但是因为业务需要又不得不做。

TeaVM就为我们这种情况提供了一种解决方案,我们的后端开发人员依然使用自己熟悉的语言(java)进行开发。功能开发完成后再将_.class或_.jar文件通过TeaVM编译成wasm或JavaScript供浏览器加载调用。

git:https://github.com/konsoletyper/teavm

官网:https://teavm.org/

6 WebAssembly可以用在哪?

目前大多数浏览器厂商都已经支持WebAssembly,包括Chrome、Edge、Firefox和Safari。移动端Web浏览器也同样支持。Node.js也从版本8开始支持。

WebAssembly不是JavaScript的替代品,而是它的一个补充,有些情况下WebAssembly是更好的选择,有些情况下使用JavaScript会是一个更优的方案。与JavaScript在同一个VM运行可让两种技术相辅相成。

WebAssembly为非JavaScript的开发者提供了一个新的道路,帮助他们在web中使用自己编写的代码。也让不了解C或C++等语言的web开发者可与访问更新、更快的库。个人理解WebAssembly也可用来优化某些库的执行速度。

6.1 一些使用webAssembly的案例

Figma — 基于浏览器的多人实时协作 UI 设计工具:https://www.figma.com/

Google Earth https://earth.google.com/ - 17年开始支持在FireFox打开,主要依赖webAssembly。之前使用Native Client导致只能在chrome中运行

Magnum — 跨平台的 OpenGL 图形引擎https://github.com/mosra/magnum

Egret Engine - 一款HTML5游戏引擎https://github.com/egret-labs/egret-core/

Web-DSP — 使用浏览器就能即时制作多媒体影音特效https://github.com/shamadee/web-dsp

7 WebAssembly怎么用?

7.1 得到wasm文件手动引入

var importObject = {imports: {imported_func: function(arg) {console.log(arg);}}};// 输出 42fetch('simple.wasm').then(res =>res.arrayBuffer()).then(bytes =>WebAssembly.instantiate(bytes, importObject)).then(results => {results.instance.exports.exported_func();});

7.2 得到编译好的npm包引入执行

// alert(`Hello, ${name}`)
const js = import("./node_modules/@jdl/hello-wasm/hello_wasm.js");
js.then(js => {js.greet("WebAssembly");
});

以下为hello_wasm.js文件编译前源码

// rust
extern crate wasm_bindgen;use wasm_bindgen::prelude::*;#[wasm_bindgen]
extern {pub fn alert(s: &str);
}#[wasm_bindgen]
pub fn greet(name: &str) {alert(&format!("Hello, {}!", name));
}

本文从为什么需要WebAssembly、WebAssembly的工作原理、哪些语言可用来创建WebAssembly模块、WebAssembly可以用在哪里 以及 怎么使用 几方面简要介绍了webAssembly。如果之前没有了解过webAssembly,可以做一些简要的了解。

参考文献

《WebAssembly 实战》 —- C. 杰勒德·加伦特

编译 Rust 为 WebAssembly - WebAssembly | MDN

作者:京东物流 潘维高

来源:京东云开发者社区 自猿其说Tech

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/13831.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Visual Studio】VS调用tensorflow C++API的配置(无需编译)

windows利用vs2015调用tensorflow c api 1. 首先下载并安装visual studio Visual Studio 2015 安装教程(附安装包),按照博客中顺序来就可以 如果在安装过程中提示安装包丢失或损坏,参考VS2015安装过程中安装包丢失或损坏解决办…

策略模式的实现与应用:掌握灵活算法切换的技巧

文章目录 常用的设计模式有以下几种:一.创建型模式(Creational Patterns):二.结构型模式(Structural Patterns):三.行为型模式(Behavioral Patterns):四.并发…

Spring注解系列——@PropertySource

在Spring框架中PropertySource注解是非常常用的一个注解,其主要作用是将外部化配置解析成key-value键值对"存入"Spring容器的Environment环境中,以便在Spring应用中可以通过Value或者占位符${key}的形式来使用这些配置。 使用案列 // Propert…

基于Citespace、vosviewer、R语言的文献计量学可视化分析及SCI论文高效写作方法教程

详情点击链接:基于Citespace、vosviewer、R语言的文献计量学可视化分析技术及全流程文献可视化SCI论文高效写作方法 前言 文献计量学是指用数学和统计学的方法,定量地分析一切知识载体的交叉科学。它是集数学、统计学、文献学为一体,注重量…

如何用非root账号安装k8s集群

在大多数情况下,为了安装 Kubernetes(K8s)集群,需要具有root权限或者以root身份执行某些操作,例如安装软件包和配置系统级别的设置。然而,你可以通过以下方法在非root账号下安装K8s集群: 使用Mi…

c语言预处理指令详解

//extern int ADD(int x, int y);//声明引用外部文件 //c语言预处理 // 文本文件 翻译链接 二进制文件 运行 //test.cpp————————》test.exe————————》 // 编译器 翻译环境 链接器 执行环境 // test.obj(目标文件&a…

工业边缘计算为什么?

在工厂环境中使用边缘计算并不新鲜。可编程逻辑控制器(PLC)、微控制器、服务器和PC进行本地数据处理,甚至是微型数据中心都是边缘技术,已经在工厂系统中存在了几十年。在车间里看到的看板系统,打卡系统,历史…

Flowable中间事件-中间信号捕获事件

定义 信号中间事件分为 Catching 事件和 Throwing 事件,即信号中间捕获事件(Signal Intermediate Catch Event)和信号中间抛出事件(Signal Intermediate Throwing Event)。 当流程执行到信号中间捕获事件时就会中断在…

什么是ROC曲线

ROC曲线(Receiver Operating Characteristic Curve),也称为“接受者操作特性曲线”。它最早应用于雷达信号检测的分析,后来广泛应用于心理学和医学领域。 ROC分析是进行临床诊断试验评价最常用的方法。诊断试验是指评价某种疾病诊…

Xshell配置ssh免密码登录-公钥与私钥登录linux服务器

目录 简介 提示 方法步骤 步骤1:生成密钥公钥(Public key)与私钥(Private Key) 方法1:使用xshell工具 方法2:使用命令行 步骤2:放置公钥(Public Key)到服务器 方法1:(我使用的是…

InnoDB数据存储结构

一. InnoDB的数据存储结构:页 索引是在存储引擎中实现的,MySQL服务器上的存储引擎负责对表中数据的读取和写入工作。不同存储引擎中存放的格式一般不同的,甚至有的存储引擎比如Memory都不用磁盘来存储数据,这里讲讲InooDB存储引擎…

深度学习调参指南

1. 选择合适的模型架构 模型的结构(层数和宽度),参数配置,尽量用已经有效的模型 2. 选择优化器 针对具体的问题,从选择常用的优化器开始,进行比较 3. 选择BatchSize 1). Batch Size决定训练速度,但是不影响验证集…

WPF实战学习笔记23-首页添加功能

首页添加功能 实现ITodoService、IMemoService接口&#xff0c;并在构造函数中初始化。新建ObservableCollection<ToDoDto>、 ObservableCollection<MemoDto>类型的属性&#xff0c;并将其绑定到UI中修改Addtodo、Addmemo函数&#xff0c;将添加功能添加 添加添加…

NineData支持最受欢迎数据库PostgreSQL

根据在 Stack Overflow 发布的 2023 开发者调研报告中显示&#xff0c;PostgreSQL 以 45% vs 41% 的受欢迎比率战胜 MySQL&#xff0c;成为新的最受欢迎的数据库。NineData 也在近期支持了 PostgreSQL&#xff0c;用户可以在 NineData 平台上进行创建数据库/Schema、管理用户与…

解决AttributeError: ‘DataParallel‘ object has no attribute ‘xxxx_fc1‘

问题描述 训练模型时&#xff0c;分阶段训练&#xff0c;第二阶段加载第一阶段训练好的模型的参数&#xff0c;接着训练 第一阶段训练&#xff0c;含有代码 if (train_on_gpu):if torch.cuda.device_count() > 1:net nn.DataParallel(net)net net.to(device)第二阶段训练…

Linux环境Arduino IDE中配置ATOM S3

linux选择ubuntu发行版。 硬件设备有多小呢&#xff1a; 功能超级强大。 之前的ROS1和ROS2案例已经全部移植完成并测试结束&#xff08;三轮纯人力校验&#x1f60e;&#xff09;。 官网文档信息非常非常好&#xff1a; https://docs.m5stack.com/zh_CN/quick_start/atoms3…

Jenkins 配置maven和jdk

前提:服务器已经安装maven和jdk 一、在Jenkins中添加全局变量 系统管理–>系统配置–>全局属性–>环境变量 添加三个全局变量 JAVA_HOME、MAVEN_HOME、PATH 二、配置maven 系统管理–>全局工具配置–>maven–>新增 新增配置 三、配置JDK 在系统管…

java策略模式

在Java中&#xff0c;策略模式&#xff08;Strategy Design Pattern&#xff09;用于定义一系列算法&#xff0c;并将每个算法封装成单独的类&#xff0c;使得它们可以互相替换&#xff0c;让客户端在使用算法时不需要知道具体的实现细节。策略模式是一种行为型设计模式&#x…

科普 | OSI模型

本文简要地介绍 OSI 模型 1’ 2’ 3。 更新&#xff1a;2023 / 7 / 23 科普 | OSI模型 术语节点链路协议网络拓扑 概念作用结构应用层表示层会话层传输层网络层数据链路层物理层 数据如何流动OSI 和TCP/IP 的对应关系和协议参考链接 术语 节点 节点&#xff08; Node &#…

Go 语言切片是如何扩容的?

在 Go 语言中&#xff0c;有一个很常用的数据结构&#xff0c;那就是切片&#xff08;Slice&#xff09;。 切片是一个拥有相同类型元素的可变长度的序列&#xff0c;它是基于数组类型做的一层封装。它非常灵活&#xff0c;支持自动扩容。 切片是一种引用类型&#xff0c;它有…