2KB项目,专业的源码交易网站 帮助 收藏 每日签到

关于使用asm.js解决一个浏览器插件障碍的想法

  • 时间:2019-01-23 18:38 编辑:2KB 来源:2KB.COM 阅读:344
  • 扫一扫,手机访问
  • 分享
摘要:
asm.js 英文原文:Thoughts on using asm.js for performance bottlenecks in browser extensions asm.js 现在是一个大新闻,而且是利好的大新闻。Firefox22上运行的一些Javascript代码性能几乎媲美那些用C/C++编译的应用程序 —— 这可是天大的头条啊。而这引起了我的兴趣:也许asm.js可以用来提升Adblock Plus的性能是吧?所以我花了一个晚上研究asm.js 和 Emscripten。这篇文章总结了到现在为止几乎我所有的想法,它并不是一般意义上的全局概览,而且其中我的一些结论也可能是错误的。    Adblock Plus有一些到目前为止我都感觉无能为力的众所周知的性能瓶颈。更糟糕的是,同样的代码会严重侵占内存的使用,C++则能够在处理和存储这些数据时表现得更加高效。因而在过去的某些时候我甚至想过要自己实现一个本地库来处理对性能要求严格的任务,但那样会有一个大问题:那种库应该需要能在所有安装了Firefox的主流平台(目前是Windows X86, Windows X64, Linux X86, Linux X64 和 OS X)上运行,所以扩展包需要包含针对每一种平台的构建,而这样就会严重增大它的体积,而同样的Javascript代码作为没有被涵盖进的平台上的后背选择仍然需要。另外,那种尝试并不会给Adblock Plus在Chrome上的性能表现带来帮助 —— 它应该仍然需要另外一种方案,兴许是 PNaCI。  

asm.js的问世似乎使这些考虑都过时了。那种C++库可以使用Emscripten编译到asm.js中。这样同样的代码就能在任何平台上运行,而且在Firefox和Chrome上都能运行的很快。而它最大的好处就是:它在老版本的Firefox中仍然可以运行,只不过不会同新的版本一般的快。理论上到目前为止,是时候来深入探讨其复杂的细节了。

尝试一下Emscripten

咋一看,Emscripten是一个Python脚本的集合,可以简单的通过从资源库检出而被“安装”。不走运的是,依赖清单上面列出了其它一些需要安装的包:LLVM, Clang和node.js。在Linux上安装这些东西相当简单,但在我的Linux发行版上可用的版本太低了。当然对我来说这并不是一个大问题,但强制用这些依赖包构建Adblock Plus有没人会告诉你的特殊的方式。

运行 gemcc -O2 -s ASM_JS=1 test.cpp 会生成相当大的文件,即使是一些琐碎的代码页至少也得60kb。 瞄一眼就明白其中大部分都是模式化的,包括了许多用来适应不同环境的代码: node.js,web页面,网络工作者,shell。目标环境(shell可能最适合用来扩展代码了)难道就不能在编译时指定么?我找不到任何办法。

一旦你接触到要使用用C++提供的功能,代码的尺寸就会像小气球一样往上窜。特别是当你用std::string做任何事情的时候,都会生成超过500kb的代码。这几乎就意味着标准库对于大多数扩展而言存在限制,否则扩展包很容易就会变得太大。不幸的是,这会让整个解决方案明显不那么方便。  

接下来我必须想想办法让其它的扩展代码同asm.js的代码能够互相通信。Emscripten 文档列出了两种选择:不那么方便一点的通过Method.cwrap()方式和更加方便一点的tembind方式。前者不允许将类映射到Javascript中,而后者不幸又需要你在代码体积上付出沉重的代价(即使没有功能输出也需要100kb)。 所以这就是所谓的API坦途——除非你有好的理由来选择更加的方便的方式。

对我而言重要的问题是:你如何能够将一个字符串传入到已经编辑的代码中? 而奇葩的是C++中字符串参数被有点反直观的映射成了tochar*而不是wchar_t*。一些实验中有这样的解释:所有的字符串都会转换成UTF-8编码。这意味着从Javascript中传入的字符串长度如果没有首先用UTF-8解码,在C++中就不可用(它会用Unicode字符引用,而不是使用UTF-8编码的字节),这使得在没有做过有条件转换的前提下使用字符串成了一件相当复杂的事情。  

但是其优点是不是足以弥补这两者双向转换的缺陷了呢——转换成UTF-8还有转换回来?我实现了一个简单的滚动哈希函数,一次用的是C++(用UTF-8编码)还有一次用的是Javascript。但当我在目前的Firefox Nightly中测试者两者的时候,常规版本的Javascript大概要快上10%左右。当然,这也许就表明了我的UTF-8解码器不够高效吧。然而我使用的解码算法绝对不算是最慢的。而在Adblock Plus中为其带来性能瓶颈的地方就在对字符串的操作上,在转换上耗费了太多性能可能就意味着(利用C++)增加的性能不再那么明显了。 

看一看原生的asm.js

Emscripten目前似乎并不怎么满足我的需求: 它主要是为了移植大量遗留的代码库,而不是加速相对只占一小部分的Javascript代码。但如果手工去写asm.js的代码又会怎么样呢?毕竟,它同常规的Javascript代码并没有多大不同,你几乎只需要遵循很少的一些规则,如果你不这么做,验证器也会告诉你这么做。对于代码较少的部分这还是可以接受的。

深入文档,这里最大的挑战似乎就是处理堆的工作了。asm.js中的变量只能够使用原生的整型和浮点型指针 。比这些更加高级的(数组,结构体类型,字符串)就需要被分配到定义了类型的数组中代表堆。而“分配”则意味着手工的内存管理,你必须且不得不重新实现malloc()函数。   

还有其它的难题:堆的大小是固定的。asm.js代码只能处理一个缓冲区,而且不能改变其大小(当然,那也会影响Emscripten生成的代码)。问题是:我也没有办法告知Adblock Plus需要多少内存呀,这严重依赖于用户的设置。如果原来模块中内存小,那就很可能会自动创建带有不同堆的新的asm.js模块——而这样的话不同模块之间处理相同的数据就不会那么容易了。

最后,有些事情对于其他人可能没什么大不了的,但对于Adblock Plus却不是这样:这里不存在哈希表。在Adblock Plus不去使用它们是不可能的,因为它们是算法的重要组成部分。而这意味着哈希表需要在asm.js中重新实现。而我绝对不会认为那会有什么乐趣可言。   

现在该怎么办呢?

所有这一切使得用asm.js来提升扩展的运行速度看起来似乎变成了一项复杂的挑战。此时很难想象Emscripten将会在扩展中得到许多的应用,因为生成的代码很容易变得很大,而字符串的转换则会损耗过多的性能。我所期望的工作应该是作为asm.js相对简单的超集的编译器,来打破asm.js的这些常规。使用手写的代码使得asm.js可用性增强并不需要太多东西:变量的类型声明,结构体类型和命名空间/对象看来就是最最重要的遗漏。一些通用辅助器可以来自动的管理堆,而使用哈希表则应该使得可用的代码被生产出来。但是,仍然不能有条件的分配内存在我看来则是另外一个需要在标准中明确的重要问题。 

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。 2KB翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。


2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务

  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【计算机/互联网|】Nginx出现502错误(2020-01-20 21:02)
【计算机/互联网|】网站运营全智能软手V0.1版发布(2020-01-20 12:16)
【计算机/互联网|】淘宝这是怎么了?(2020-01-19 19:15)
【行业动态|】谷歌关闭小米智能摄像头,因为窃听器显示了陌生人家中的照片(2020-01-15 09:42)
【行业动态|】据报道谷歌新闻终止了数字杂志,退还主动订阅(2020-01-15 09:39)
【行业动态|】康佳将OLED电视带到美国与LG和索尼竞争(2020-01-15 09:38)
【行业动态|】2020年最佳AV接收机(2020-01-15 09:35)
【行业动态|】2020年最佳流媒体设备:Roku,Apple TV,Firebar,Chromecast等(2020-01-15 09:31)
【行业动态|】CES 2020预览:更多的流媒体服务和订阅即将到来(2020-01-08 21:41)
【行业动态|】从埃隆·马斯克到杰夫·贝佐斯,这30位人物定义了2010年代(2020-01-01 15:14)
联系我们

Q Q: 7090832

电话:400-0011-990

邮箱:7090832@qq.com

时间:9:00-23:00

联系客服
商家入住 服务咨询 投拆建议 联系客服
0577-67068160
手机版

扫一扫进手机版
返回顶部