是还是不是?

我们在Linkurious正在努力Linkurious企业。它是一个基于Web的平台,它使用图表的强大功能及其可视化工具来帮助全球的公司和当局打击金融犯罪。



Linkurious Enterprise的主要功能之一是专为外行设计的易于学习且易于使用的图形可视化界面。 2015年,由于现有的JavaScript库可用于图形可视化而感到沮丧,我们开始开发自己的库-Ogma。











Ogma是旨在呈现网络结构的呈现和计算性能的JS库。您可能已经了解了如何使用其他JavaScript工具(例如D3.js或Sigma.js)呈现网络结构。我们缺乏这些工具的功能。对我们而言,重要的是,我们使用的解决方案将具有一些特定的功能,以便能够满足某些性能要求。我们在第三方库中找不到任何一个。因此,我们决定从头开始开发自己的库。



任务





网络结构可视化



Ogma库旨在使用最先进的算法。它的所有组件,从基于WebGL的高级渲染引擎到深入使用的Web工作人员,都旨在为渲染网络结构提供最佳性能。我们的目标是在执行长期任务时使该库具有很高的交互性,从而使其中实现的领先的图形可视化算法能够快速,稳定地工作。



从首次报道以来,WebAssembly(Wasm)技术就已经向Web开发人员保证了一定的性能水平,可以与他们以前获得的性能相比。同时,开发人员自己不需要为使用新技术付出过多的努力。他们只需要用他们知道的一些高性能语言编写代码,这些语言在编译后就可以在浏览器中运行。



在Wasm技术有所发展之后,我们决定在实施之前尝试一下并进行一些性能测试。通常,在不回头的情况下跳入快速Wasm列车之前,我们决定安全使用。



Wasm吸引我们的是,这项技术可以很好地解决我们的问题,比JavaScript更有效地使用内存和处理器资源。



我们的研究



我们的研究始于寻找一种旨在处理图形的算法,该算法可以使用相似的数据结构轻松移植到不同的语言。



我们选择了n体算法。它通常用作比较力图可视化算法的基准。根据此算法执行的计算是可视化系统中资源最密集的部分。如果这样的系统的这一部分工作能够比以前更有效地完成,那么它将对在Ogma中实现的所有力图可视化算法产生非常积极的影响。



基准测试



有谎言,重大谎言和基准。



马克斯·德·马齐(Max De Marzi)



建立“诚实”的基准通常是不可能完成的任务。事实是,在人工创建的环境中,很难重现现实世界中的典型场景。为复杂的系统创建适当的环境始终非常困难。确实,在实验室环境中,很容易控制外部因素,但实际上,许多意外因素会影响解决方案的“性能”。



在我们的案例中,基准测试旨在解决一个明确定义的问题,以研究n体算法实现的性能。



这是一种著名的组织用来衡量绩效的清晰且有据可查的算法编程语言。



与任何公平测试一样,我们为我们研究的各种语言预先定义了一些规则:



  • 该算法的不同实现应使用相似的代码结构。
  • 禁止使用多个进程或多个线程。
  • 禁止使用SIMD
  • 仅测试稳定版本的编译器。禁止使用每晚,beta,alpha,pre-alpha之类的发行版。
  • 每种语言仅使用最新的编译器版本。


在确定规则之后,我们就可以继续执行算法了。但是在这样做之前,我们还必须选择我们将要研究其性能的语言。



JS竞争对手



Wasm是在浏览器中运行的指令的二进制格式。用各种编程语言编写的代码被编译成这种格式。他们说Wasm代码是人类可读的代码,但是直接用Wasm编写程序并不是一个理智的人可以做出的决定。因此,我们进行了基准调查并选择了以下候选人:





用这三种语言实现了n体算法。将各种实现的性能与基本JavaScript实现的性能进行了比较。



在算法的每个实现中,我们使用1000点,然后以不同的迭代次数运行算法。我们测量了完成每个程序会话所花费的时间。



使用以下软件和硬件进行了测试:



  • NodeJS 12.9.1
  • Chrome 79.0.3945.130(正式版本)(64位)
  • clang 10.0.0-用于以C语言实现的算法版本
  • emcc 1.39.6-前端,用于从命令行调用Emscripten编译器,gcc / clang的替代方法以及链接器
  • 货物1.40.0
  • wasm-pack 0.8.1
  • AssemblyScript 0.9.0
  • MacOS 10.15.2
  • Macbook Pro 2017视网膜
  • 英特尔双核i5 2,3 GHz,8GB DDR3、256GB SSD


如您所见,对于测试,我们选择的不是最快的计算机,而是测试Wasm,即将在浏览器上下文中执行的代码。而且,无论如何,浏览器通常都无法访问系统中可用的所有处理器内核以及所有RAM。



为了使它更有趣,我们为算法的每个实现创建了多个版本。在n体系统的某一点上,它们具有64位的坐标数字表示,在另一点上具有32位的坐标表示。



还值得注意的是,我们在Rust中使用了算法的“双重”实现。首先,在不使用任何Wasm工具的情况下,编写了“本机”,“不安全” Rust实现。后来,使用wasm-pack,创建了另一个“安全” Rust实现。预计该算法的实现将更易于与JS集成,并且可以更好地管理Wasm中的内存。



测试中



我们在两个主要环境中进行了实验。这是Node.js和浏览器(Chrome)。



在这两种情况下,都是使用热脚本执行基准测试。即,在运行测试之前未启动垃圾收集。当我们在运行每个测试之后运行垃圾回收时,它似乎对结果没有太大影响。



基于AssemblyScript编写的源代码,生成了以下内容:



  • 该算法的基本JS实现。
  • Wasm模块。
  • Asm.js模块。


有趣的是,asm.js模块与asm.js不完全兼容。我们尝试在模块顶部添加“ use asm”指令,但浏览器不接受此优化。后来我们发现,我们使用的二进制编译器并不是真的试图使代码与asm.js完全兼容。相反,它专注于形成某种高效的Wasm JS版本。



我们首先在Node.js中运行测试。





在Node.js环境中运行代码



然后,我们在浏览器中测量了相同代码的性能。





在浏览器中运行代码



我们立即注意到,代码的asm.js版本比其他选项慢。但是这些图不允许我们清楚地将各种代码变体的结果与算法的基本JS实现进行比较。因此,为了更好地理解所有内容,我们构建了一些其他图表。





该算法的其他实现与JS实现之间的区别(具有64位点坐标的基准版本)





该算法的其他实现与JS实现(具有32位点坐标的



基准版本)之间的差异具有64位和32位点坐标的基准版本明显不同。这可能使我们认为,在JavaScript中,数字可以同时为数字。事实是,在算法的实现中,JS中的数字被用作比较基础,始终是64位,但是将其他语言的代码转换为Wasm的编译器以不同的方式使用此类数字。



特别是,这对测试的asm.js版本具有巨大影响。其具有32位点坐标的版本在性能上远低于基本JS实现和使用64位数字的asm.js版本。



在前面的图中,很难理解其他代码变体的性能与JS变体之间的关系。这是因为AssemblyScript的度量标准与其他度量标准完全不同。为了理解这一点,我们构建了另一个图,删除了asm.js的结果。





该算法的其他实现与JS实现之间的区别(具有64位点坐标的基准版本,没有asm.js)





该算法的其他实现与JS实现(具有32位点坐标的基准版本,没有asm.js)之间的



差异。数字的不同表示似乎已经影响了该测试的其他版本。但是他们以不同的方式影响。例如,使用32位数字(浮点数)的C变体比使用64位数字(双精度数)的C变体慢。具有32位数字(f32)的两个Rust版本的测试变得比具有64位数字(f64)的版本更快。



算法执行不佳?



对以上数据的分析可能提出以下想法。由于所有测试过的Wasm程序集的性能都非常接近JavaScript实现,因此Wasm实现是否可能仅反映本机算法实现的性能特征?





将算法的本机实现与JavaScript实施进行比较算法实现的本



机版本始终比JavaScript实现快。



我们还注意到,Wasm程序集比用于创建此类程序集的代码的本机版本慢。性能差异为20-50%。我们在经过1000次迭代的缩短版基准中发现了这一点。





C实现和相应的Wasm组件





Rust实现和相应的Wasm构建





使用wasm-pack和相应的Wasm程序集创建的Rust实现。



在测量本机代码的执行时间时,考虑了加载程序所需的时间,对于Wasm变体,则不考虑该时间。



结果



与基本的JS实现相比,该算法的两个Rust实现平均而言具有20%的性能提升。这可能对Rust的图像很有好处,但是与获得它所付出的努力相比,它的性能提升很少。



从这些测试中我们可以得出什么结论?这里是一些:精心编写JS代码可以使您获得相当高的性能,而无需切换到其他编程语言。



学习新的编程语言总是很不错的。但是学习新语言肯定有充分的理由。性能通常是“错误”的原因,因为高级设计体系结构对性能的影响比编译器或微优化更为重要。



作为实验,我们将JavaScript更改为TypeScript,以编写力图可视化算法的实现。结果,我们提高了代码库的质量,但没有提高性能。我们专门测量了性能,结果发现在过渡之后,它略微提高了5%。原因可能是代码重构。



如果您对JavaScript开发和性能问题感兴趣,那么您可能有兴趣观看演讲,听起来与我们得到的结果相似。



您如何处理Web项目“繁重”部分的开发?






All Articles