初识WebAssembly:灵活可移植高性能
Posted k8s技术圈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初识WebAssembly:灵活可移植高性能相关的知识,希望对你有一定的参考价值。
在本文中,我将简单向你介绍WebAssembly。首先,我们会简单了解汇编语言的历史,因为这一语言使得编程更加轻松并且提升了生产力。然后,我们就切入正题,了解WebAssembly,包括它是什么、它解决了什么问题以及它的工作机制。
汇编语言的历史
几十年前,如果你想为计算机编程,你必须得写二进制代码。我们将其称为机器码(machine code),因为它是计算机的原生语言(也许这将随着量子计算的兴起而改变,但就目前而言,每台计算机都在二进制代码上工作)。机器码可以直接在计算机上运行,不需要编译器、转码器或其他高级操作。
编写机器代码并对其进行调试并不是一项简单的任务,因此计算机专家们意识到他们需要一个更高级的语言来提升生产力并且让计算机编程更简单。基于此,汇编语言应运而生。与机器代码相比,该语言更简单也更好理解,因为它使用的指令不是0和1,而是更接近人类语言的指令,如add、mul、div、mov等。
为了翻译用汇编语言编写的代码,你需要一个assembler和一个linker。然而,在汇编语言和机器码之间仍然存在着1比1的关系,这意味着一条汇编指令将被翻译成机器码中的确切指令。这在高级语言如C、C++、C#等中是不存在的。因为汇编语言非常接近于机器代码,所以它的速度也非常快(比任何高级语言都快,因为高级语言需要被编译)。随着代码复杂性的增加,编译器将越来越难生成高效和优化的机器码,这意味着性能降低。因此,如果你需要高性能,理想的选择是汇编语言。
与汇编语言相比,高级语言有其优势,如提高生产力、更容易维护和具备可移植性,但它们无法与汇编语言的性能优势进行竞争。
WebAssembly介绍
现在我们要开始讨论的问题是“什么是WebAssembly”。我们可以说,WebAssembly是网络应用程序的汇编语言。但这只是部分正确,因为WebAssembly是一种字节码(byte code),而汇编语言是一种转换为字节码的语言。WebAssembly试图创造的是尽可能快地运行的语言,接近汇编的速度,但应用场景在网络上,因此而得名。
下一个问题是“ 为什么我们需要WebAssembly,它能解决什么问题?”这时候我们应该提一下javascript。不要误会,Javascript固然是一种伟大的语言,但在性能方面依旧存在问题。
为什么Javascript这么慢?其中一个主要原因是Javascript是动态类型的,这意味着一个变量可以存储任何类型的数据,从简单的ints、到字符串,甚至更复杂的类型如数组或对象。这在编写代码时可能是一个优势,但静态类型的语言,如C、C++等,会产生更有效的机器码。在这些情况下,编译器拥有每个变量的类型和大小信息。
Javascript比WebAssembly慢的另一个原因是,它需要更多的步骤来解析它。解析JavaScript需要将纯文本转换为抽象语法树(AST),然后将其转换为二进制表示。WebAssembly使用二进制格式,这使得解码的速度更快。WebAssembly代码是静态类型的,所以Javascript引擎不需要在编译时猜测变量的类型。WebAssembly代码的优化发生在编译过程中,所以没有额外的优化步骤。在下图中,我们可以看到将Javascript或WebAssembly转换为可执行代码所需的步骤:
Javascript 旨在仅显示静态页面。它是为了提供一个操作DOM的API而创建的,因此没有考虑到性能。现在,我们在网络上有很多 CPU 密集型计算,比如物理、人脸检测,可能还有一些机器学习等,对于这些 CPU 密集型任务,Javascript 已经不够用了。
另一个问题是,在网络上,除了 Javascript 之外,您没有太多选择。在后端,有多种选择,如C、C++、C#、Java等,但是当涉及到 Web 时,,你就只能用Javascript了。当然,还有其他语言,例如 Typescript,但所有这些语言都以某种方式在 Javascript 中进行了转换或“转译”。
这就是WebAssembly所要解决的问题。WebAssembly这个词的灵感来自于汇编语言,它在机器码中生成优化和高速的程序,并且完全在网络平台中运行。这意味着你可以将用于CPU密集型计算的WebAssembly库(如压缩、人脸识别和物理学)集成到目前使用Javascript进行低强度工作的网络程序中。
如果我们想尽可能简单地定义WebAssembly,那么可以认为它是为浏览器编译的二进制代码。
除了提高性能,WebAssembly还有一个重要的特点:它是一个通用的编译目标。这意味着我们不再依赖Javascript,我们可以用任何我们想用的语言(C、C++、C#等)编写代码,并将其编译成WebAssembly。你可以访问下方链接查看可以用WebAssembly编译的语言列表:
https://github.com/appcypher/awesome-wasm-langs
WebAssembly工作机制
在C、C++、C#等高级语言中,我们编写的代码可以在多个处理器上运行,这意味着该代码拥有可移植性。但我们是如何解决可移植性问题的呢?我们添加了一层抽象,一个 “虚拟处理器”(the interpreter),它解释中间字节码,并将其变成与特定处理器兼容的字节码。在interpreter之前或之后,我们可以添加一个优化步骤,但我们现在不想让步骤变得如此复杂。
在WebAssembly中,理念是类似的,但是针对的是不同的浏览器而非处理器。
这样,我们可以用任何高级语言编写代码(可以用.wasm编译,这是WebAssembly二进制代码的文件扩展名),它就可以在浏览器中运行。这意味着CPU密集型的算法可以用C语言编写,并在浏览器中运行,解决了可移植性的问题,极大地提高了其性能。
这并不意味着我们不再需要Javascript了。对于CPU密集型的计算,WebAssembly有巨大优势。但是它无法直接访问DOM,所以它在DOM操作方面比JavaScript慢,因为它有额外的I/O开销。
因此,WebAssembly和Javascript的结合是一个强大的工具,因为Javascript可以专注于DOM操作,而WebAssembly可以处理CPU密集型任务。
通常情况下,我们在使用WebAssembly时架构如下:
所以,WebAssembly只是浏览器可以下载的另一种文件,而Javascript是WebAssembly和网络应用之间的粘合剂。在这种情况下,app.js可以与DOM交互,但它也可以与WebAssembly交互,反之亦然。但是,如上图所示,WebAssembly不能与DOM交互。因此对于动态和交互式 Web 应用程序,我们仍然需要 Javascript。所以,如果我们想用WebAssembly来操作DOM,它就需要与Javascript对话,操作DOM。这就是为什么用WebAssembly操作DOM比直接使用Javascript慢的原因。
WebAssembly的优势
即使每个人都在谈论WebAssembly的优势都会提及性能,但在我看来,这并不是它最大的优势。当然,在一些特定的使用情况下,WebAssembly比Javascript有更高的性能,但是当涉及到DOM时,Javascript就处于上风了。
在我看来,WebAssembly带来的最重要的优势是可移植性和灵活性。
要在一个设备上运行一个应用程序,它必须与处理器的架构和设备的操作系统兼容。如果没有可移植性,你必须为每个处理器架构和操作系统的组合编译相同的代码。有了WebAssembly,只需一个编译步骤,它就可以在所有浏览器上运行。
另一个显著的优势是灵活性。在WebAssembly之前,我们一直有这样的挫折感:在网络上除了Javascript之外没有任何选择。但有了WebAssembly,你可以用你喜欢的编程语言编写代码,将其编译为.wasm(WebAssembly的扩展名)即可运行。因此,你可以用C、C++、C#(见Blazor项目:https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor)等高级语言编写网络应用程序。此外,在优化性能时,可以用更好的语言重写现有 Javascript 程序中的瓶颈。
总 结
这篇文章介绍了WebAssembly,它为什么被创造出来,它解决了什么问题,以及它如何解决这些问题。
WebAssembly是一种伟大的语言,它为web开发开辟了一个全新的世界,因为程序员可以选择他们喜欢的任何语言来编写web应用。随着WebAssembly的兴起,我们有了其他选择来构建我们的网络应用,而不仅仅是Javascript。
PNaCl 再见,WebAssembly 你好!
过去,在网页上运行原生代码需要有浏览器插件。2013 年,为了无需借助插件,直接构建安全、可移植的高性能应用,我们推出了 PNaCl 沙盒。尽管这种方法在 Chrome 中工作良好,但它并不能提供一种能够在所有浏览器中无缝工作的解决方案。
自那以后,网络社区开始合力推动 WebAssembly 作为构建高性能代码的跨浏览器解决方案。WebAssembly 利用基于现有标准的网络平台 API 来提供构建浏览器内视频编辑器或高帧速运行 Unity 游戏所必要的速度。使用 WebAssembly 的应用已在多种浏览器上运行:Chrome 和 Firefox 均原生支持 WebAssembly,Edge 和 Safari 则在其预览版浏览器中支持 WebAssembly。
考虑到跨浏览器支持乃是大势所趋,我们计划今后主要依靠 WebAssembly 构建原生代码。我们将于 2018 年第一季度在除 Chrome 应用和扩展程序内部以外的任何应用中取消对 PNaCl 的支持。我们相信:围绕 WebAssembly 而建立的生态系统使其更适合新的和现有的高性能网络应用,而使用 PNaCl 的应用已经很少,足以证明是时候弃用它了。
我们深知:技术的迁移充满挑战。为了帮助简化迁移流程,我们准备了关于如何将现有 PNaCl 实现迁移到网络平台的一系列建议,还制作了一份 WebAssembly 功能路线图:
https://wasmdash.appspot.com
在您着手实施迁移流程时,如果遇到任何难题,请告诉我们,以便我们能够帮助您尽可能顺利地完成迁移。
随着 WebAssembly 的发布,网络平台为新一代可在任何浏览器中快速运行的沉浸式网络应用奠定了坚实的基础。我们期待看到开发者接下来将开发出多么精彩的应用!
推荐阅读:
以上是关于初识WebAssembly:灵活可移植高性能的主要内容,如果未能解决你的问题,请参考以下文章