加速使用WebAssembly 20x Web应用程序

图片

本文讨论了通过用WebAssembly替换JavaScript来加速浏览器应用程序的情况。

WebAssembly-什么?


简而言之,这是用于堆叠虚拟机的二进制指令格式。 Wasm(简称)通常被称为一种编程语言,但事实并非如此。 指令格式与JavaScript一起在浏览器中执行。

可以通过编译C / C ++,Rust,Go等语言的源代码来获取WebAssembly,这一点很重要。 它使用静态类型和所谓的平面内存模型。 如上所述,代码以紧凑的二进制格式存储,因此它的运行速度几乎与使用命令行启动应用程序的速度一样。 这些功能导致WebAssembly的日益普及。

我们提醒您: 对于所有“ Habr”读者来说,使用“ Habr”促销代码注册任何Skillbox课程时均可享受10,000卢布的折扣。

Skillbox建议:实用课程“ Mobile Developer PRO”

Wasm当前在许多应用程序中使用,从诸如《毁灭战士3》之类的游戏到移植到诸如Autocad和Figma之类的Web应用程序。 Wasm还用于无服务器计算等领域。

本文提供了一个使用Wasm加速分析Web服务的示例。 为了清楚起见,我们采用了一个用C编写的工作应用程序,该应用程序已编译为WebAssembly。 结果将用于替换JS的低生产率部分。

应用程式转换


该示例将使用针对遗传学家的浏览器服务fastq.bio。 该工具使您可以评估DNA测序(解码)的质量。

这是工作中的示例应用程序:



该过程的细节不应该给出,因为它们对于非专业人员而言相当复杂,但是简而言之,上述图表的科学家可以理解DNA测序过程是否顺利进行以及出现了什么问题。

该服务有替代方案,桌面程序。 但是fastq.bio可以通过可视化数据来加快处理速度。 在大多数其他情况下,您需要能够使用命令行,但是并非所有的遗传学家都有必要的经验。

一切都很简单。 在输入处-以文本文件形式显示的数据。 该文件由专门的排序工具生成。 该文件包含DNA序列列表和每个核苷酸的质量评估。 文件格式为.fastq,这就是服务获得名称的原因。

JavaScript实现


用户使用fastq.bio时的第一步是选择适当的文件。 应用程序使用File对象,从文件中随机选择数据并处理此包。 JavaScript的任务是执行简单的字符串操作和计数指示器。 其中之一是不同DNA片段上核苷酸A,C,G和T的数量。

在计算了必要的指标之后,可以使用Plotly.js对其进行可视化,并且该服务开始使用新的数据选择。 进行分段可以提高UX的质量。 如果您一次处理所有数据,该过程将冻结一段时间,因为具有排序结果的文件将占用数百GB的文件空间。 该服务可接收大小为0.5到1 Mb的数据,并逐步使用它们来构建图形数据。

运作方式如下:



红色矩形包含用于渲染的字符串转换算法。 就计算而言,这是服务中负载最重的部分。 值得尝试用Wasm代替它。

测试WebAssembly


为了评估使用Wasm的可能性,项目团队开始寻找现成的解决方案,以基于fastq文件创建QC指标(QC-质量控制)。 搜索是在用C,C ++或Rust编写的工具中进行的,因此可以将代码移植到WebAssembly。 此外,该工具不应“原始”,它需要科学家已验证的服务。

结果,选择了seqtk 。 该应用程序非常流行,它是开源的,源语言是C。

转换为Wasm之前,您应该查看为桌面编译seqtk的原理。 根据Makefile,这是您需要的:

# Compile to binary $ gcc seqtk.c \ -o seqtk \ -O2 \ -lm \ -lz 

基本上,您可以使用Emscripten编译seqtk。 如果不存在,请绕开Docker映像

 $ docker pull robertaboukhalil/emsdk:1.38.26 $ docker run -dt --name wasm-seqtk robertaboukhalil/emsdk:1.38.26 

如果您愿意, 可以自己收集它 ,但是需要一些时间。

在容器内,您可以轻松地将emcc替代gcc:

 # Compile to WebAssembly $ emcc seqtk.c \ -o seqtk.js \ -O2 \ -lm \ -s USE_ZLIB=1 \ -s FORCE_FILESYSTEM=1 

最小变化:

不是输出到Emscripten二进制文件,而是使用.wasm和.js生成文件,这些文件用于运行WebAssemby模块。

为了支持zlib库,使用了USE_ZLIB标志。 该库已分发并移植到WebAssembly,Emscripten将其包含在项目中。

Emscrippten虚拟文件系统已激活。 这是一个类似POSIX的FS ,在浏览器内部的RAM中运行。 页面刷新后,内存将被清除。

要了解为什么需要虚拟文件系统,有必要将从命令行启动seqtk的方式与运行已编译的WebAssembly模块的方式进行比较。

 # On the command line $ ./seqtk fqchk data.fastq # In the browser console > Module.callMain(["fqchk", "data.fastq"]) 

必须具有对虚拟文件系统的访问权限,以免用字符串而不是文件输入覆盖seqtk。 在这种情况下,数据片段在虚拟FS中显示为data.fastq文件,并调用了main()seqtk。

这是新的体系结构:



该图显示,主浏览器流使用WebWorkers而不是计算。 此方法可以在不影响浏览器响应性的情况下在后台线程中执行计算。 好了,WebWorker控制器启动了Worker,控制了它与主线程的交互。

seqtk命令是使用安装文件上的Worker启动的。 工作完成后,Worker以Promise的形式显示结果。 当主线程接收到消息时,结果将用于更新调度。 如此反复。

WebAssembly的性能如何?


为了评估性能的变化,项目团队使用了每秒读取操作数的参数。 由于两种实现都使用JavaScript,因此不考虑交互式图表制作时间。

使用开箱即用的解决方案时,性能提高了9倍。



这是一个极好的结果,但是事实证明,有机会对其进行优化。 事实是seqtk没有使用大量的QC分析结果,因此您可以删除它们。 如果这样做,与JS相比,结果将提高13倍。



只需注释一下printf()命令就可以实现。

但这还不是全部。 事实是,在此阶段,fastq.bio通过调用C的不同函数来接收分析结果。它们中的任何一个都计算自己的特征集,因此文件的每个片段都被读取两次。

为了解决这个问题,决定将这两个功能合并为一个。 结果,生产率提高了20倍。



值得注意的是,这种出色的结果并非总是能够实现的。 在某些情况下,性能会下降,因此值得对每种情况进行评估。

可以断定,Wasm确实可以提高应用程序性能,但是您需要明智地使用它。

Skillbox建议:

Source: https://habr.com/ru/post/zh-CN452190/


All Articles