资讯专栏INFORMATION COLUMN

JavaScript工作原理(六):WebAssembly比较分析和特定情况下最好在JavaScri

novo / 729人阅读

摘要:我们将拆分来分析它的工作原理,更重要的是,它在性能方面如何提升加载时间,执行速度,垃圾回收,内存使用率,平台访问,调试,多线程和可移植性。目前,是围绕和用例设计的。多线程在单个线程上运行。目前不支持多线程。被设计为安全和便携。

我们将拆分WebAssembly来分析它的工作原理,更重要的是,它在性能方面如何提升JavaScript:加载时间,执行速度,垃圾回收,内存使用率,平台API访问,调试,多线程和可移植性。

我们构建Web应用程序的方式正处于革命的边缘 - 这仍然是初期阶段,但我们对Web应用程序的看法正在发生变化。

首先,让我们看看WebAssembly的功能

WebAssembly(又名wasm)是一种高效的,低级的网络字节码。

WASM使您能够使用JavaScript以外的语言(例如C,C ++,Rust或其他),在其中编写程序,然后将其编译(提前)到WebAssembly。

其结果是一个加载和执行速度非常快的Web应用程序。

加载时间

为了加载JavaScript,浏览器必须加载所有文本的.js文件。

WebAssembly在浏览器中加载速度更快,因为只有已编译的wasm文件必须通过互联网传输。而wasm是一种非常简洁的二进制格式的低级汇编语言。

执行

今天Wasm比本地代码执行速度慢20%。无论如何,这是一个惊人的结果。它是一种编译到沙箱环境中的格式,并且在很多约束条件下运行,以确保它没有安全漏洞,或者对它们非常强硬。与真正的本地代码相比,速度下降很小。更重要的是,未来它会更快。

更好的是,它与浏览器无关 - 所有主要引擎都增加了对WebAssembly的支持,并且现在提供类似的执行时间。

为了理解WebAssembly与JavaScript相比执行得有多快,您应该先阅读我们关于JavaScript引擎如何工作的文章。

我们来看看V8中会发生什么样的快速概述:

在左侧,我们有一些JavaScript源代码,包含JavaScript函数。它首先需要进行分析,以便将所有字符串转换为标记并生成抽象语法树(AST)。AST是JavaScript程序逻辑的内存表示。一旦生成这种表示,V8直接转到机器码。基本上遍历树,生成机器代码,生成你的编译后的函数。 没有真正的尝试来加速它。

现在,我们来看看V8管道在下一阶段的功能:

这次我们有TurboFan,V8的优化编译器之一。当您的JavaScript应用程序正在运行时,很多代码在V8中运行。TurboFan可以监控某些内容是否运行缓慢,是否存在瓶颈和热点以优化它们。它将它们推送到后端,这是一个优化的JIT,它为那些耗时耗力CPU的函数创建了更快的代码。

它解决了这个问题,但这里的问题在于,分析代码并决定优化哪些内容的过程也会消耗CPU。 这反过来又意味着更高的电池消耗,特别是在移动设备上。

那么,wasm并不需要所有这些 - 它会被插入工作流程中,如下所示:

在汇编阶段,wasm已经通过优化。最重要的是,解析也不是必需的。你有一个优化的二进制文件,可以直接挂接到可以生成机器码的后端。 所有优化都由编译器在前端完成。

这使得执行wasm更有效率,因为流程中的很多步骤都可以简单地跳过。

内存模型

例如,编译成WebAssembly的C++程序的内存是连续的内存块,其中没有“洞”。有助于提高安全性的wasm的特性之一是执行堆栈与线性内存分离的概念。在一个C++程序中,你有一堆,你从堆的底部分配,然后从堆顶部开始堆栈。可以带一个指针,然后在堆栈内存中查找,以便玩弄你不应该触摸的变量。

这是很多恶意软件利用的陷阱。

WebAssembly采用完全不同的模型。执行堆栈与WebAssembly程序本身是分开的,因此您无法在其中修改并更改变量等内容。而且,这些函数使用整数偏移而不是指针。函数指向一个间接函数表。然后这些直接计算的数字跳转到模块内部的函数中。它是以这种方式构建的,以便您可以并排加载多个wasm模块,并抵消所有索引,并且一切正常。

有关JavaScript中内存模型和管理的更多信息,可以查看关于该主题的非常详细的帖子。

垃圾收集

您已经知道JavaScript的内存管理是使用垃圾收集器处理的。

WebAssembly的情况有点不同。它支持手动管理内存的语言。您可以将自己的GC与您的wasm模块一起发货,但这是一项复杂的任务。

目前,WebAssembly是围绕C++和RUST用例设计的。由于wasm是非常低级的,因此编程语言只是汇编语言之上的一个步骤就很容易编译。 C可以使用普通的malloc,C++可以使用智能指针,Rust使用完全不同的范例(完全不同的主题)。这些语言不使用GC,因此它们不需要所有复杂的运行时间内容来跟踪内存。 WebAssembly对他们来说是天作之合。

另外,这些语言并不是100%设计用于调用DOM等复杂的JavaScript事物。在C++中编写整个HTML应用程序是没有意义的,因为C++不是为它设计的。在大多数情况下,当工程师编写C++或Rust时,他们的目标是WebGL或高度优化的库(例如繁重的数学计算)。

但是,将来WebAssembly将支持不附带GC的语言。

平台API访问

取决于执行JavaScript的运行时,访问特定于平台的API将被公开,可通过JavaScript应用程序直接访问。例如,如果您在浏览器中运行JavaScript,则您有一组Web API,Web应用程序可以调用它来控制Web浏览器/设备功能并访问DOM,CSSOM,WebGL,IndexedDB,Web Audio API等。

那么,WebAssembly模块无法访问任何平台API。一切都是由JavaScript调解的。如果您想访问WebAssembly模块中的某些平台特定的API,则必须通过JavaScript调用它。

例如,如果您想使用console.log,则必须通过JavaScript调用它,而不是使用C ++代码。这些JavaScript调用的成本有所降低。

这并不总是如此。该规范将在未来为平台API提供wasm,并且您将能够在没有JavaScript的情况下发布您的应用程序。

源地图

当您压缩JavaScript代码时,您需要一种正确调试它的方法。这就是Source Maps来拯救的地方。
基本上,源地图是一种将组合/缩小文件映射回未建立状态的方法。当您为生产而构建时,同时缩小和组合您的JavaScript文件,您将生成一个包含原始文件信息的源映射。当您在生成的JavaScript中查询某一行和列号时,可以在返回原始位置的源地图中执行查找。

WebAssembly目前不支持源地图,因为没有规范,但最终(可能很快)。

当您在C++代码中设置断点时,您将看到C++代码而不是WebAssembly。至少,这是目标。

多线程

JavaScript在单个线程上运行。有很多方法可以利用Event Loop并利用异步编程,如我们关于该主题的文章中详细介绍的那样。

JavaScript也使用Web Workers,但他们有一个非常具体的用例 - 基本上,任何激烈的CPU计算会阻止主UI线程,把他们放到Web Worker中将会受益。但是,Web Workers无法访问DOM。

WebAssembly目前不支持多线程。但是,这可能是未来的事情。 Wasm将接近本地线程(例如C++样式线程)。拥有“真实”的线程将在浏览器中创造出许多新的机会。当然,这将打开更多滥用可能性的大门。

可移植性

如今,JavaScript几乎可以在任何地方运行,从浏览器到服务器端甚至嵌入式系统。

WebAssembly被设计为安全和便携。就像JavaScript一样。 它将运行在支持主机的每个环境中(例如每个浏览器)。

WebAssembly具有与Java初期尝试实现的Appliets相同的目标

在JavaScript上使用WebAssembly哪里更好?

在WebAssembly的第一个版本中,主要关注CPU占用大的计算(例如处理数学)。想到的最主流的用途是游戏 - 那里有大量的像素操作。您可以使用您习惯的OpenGL绑定在C ++ / Rust中编写您的应用程序,并将其编译为wasm。它会在浏览器中运行。

看看这个(在Firefox中运行) - http://s3.amazonaws.com/mozil...。这是运行虚幻引擎。

另一种使用WebAssembly(性能方面)可能有意义的情况是实现一些库,这是一个CPU密集型工作。例如,一些图像处理。

如前所述,由于大多数处理步骤在编译期间已提前完成,因此可以减少移动设备上的电池消耗(取决于引擎)。

将来,即使您实际上没有编写编译代码,您也可以使用WASM二进制文件。您可以在NPM中找到开始使用此方法的项目。

对于DOM操作和沉重的平台API使用,使用JavaScript确实很有意义,因为它不会增加额外开销,并且API本身提供。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107746.html

相关文章

  • WebAssembly 系列(四)WebAssembly 工作原理

    摘要:但是它们其实并不是二选一的关系并不是只能用或者。正因为如此,指令有时也被称为虚拟指令。这是因为是采用基于栈的虚拟机的机制。声明模块的全局变量。。下文预告现在你已经了解了模块的工作原理,下面将会介绍为什么运行的更快。 作者:Lin Clark 编译:胡子大哈 翻译原文:http://huziketang.com/blog/posts/detail?postId=58c77641a6d8...

    stormzhang 评论0 收藏0
  • WebAssembly 那些事儿

    摘要:的目标是对高级程序中间表示的适当低级抽象,即代码旨在由编译器生成而不是由人来写。表示把源代码变成解释器可以运行的代码所花的时间表示基线编译器和优化编 WebAssembly 那些事儿 什么是 WebAssembly? WebAssembly 是除 JavaScript 以外,另一种可以在网页中运行的编程语言,并且相比之下在某些功能和性能问题上更具优势,过去我们想在浏览器中运行代码来对网...

    邱勇 评论0 收藏0
  • JavaScript 工作原理WebAssembly 对比 JavaScript 及其使用场景

    摘要:现在,我们将会剖析的工作原理,而最重要的是它和在性能方面的比对加载时间,执行速度,垃圾回收,内存使用,平台访问,调试,多线程以及可移植性。目前,是专门围绕和的使用场景设计的。目前不支持多线程。 原文请查阅这里,略有改动,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland。 本系列持续更新中,Github 地址请查阅这里。 这是 JavaScript 工作原理的第六章...

    jay_tian 评论0 收藏0
  • WebAssembly 为什么比 asm.js 快?

    摘要:并且于年月日,四个主要的浏览器一致同意宣布的版本已经完成,即将推出一个浏览器可以搭载的稳定版本。因此本文着重介绍为什么比更快。本文主要表达的是为什么应该是更快的。则不同,它是由几大主要的浏览器厂商共同设计的。 作者:Alon Zakai 编译:胡子大哈 翻译原文:http://huziketang.com/blog/posts/detail?postId=58ce80d2a6d8a0...

    Binguner 评论0 收藏0

发表评论

0条评论

novo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<