使用Emscripten编译的WebAssembly可以生成较小的文件大小

Jac*_*ope 3 emscripten webassembly

我对WebAssembly很感兴趣,但令人沮丧的是,即使是用C++编码并使用Emscripten编译的"Hello World"示例,也会在浏览器中生成总计396KB的内容.是什么赋予了?如何才能提高尺寸效率呢?

Dan*_*und 7

摘要

  • 对于像游戏引擎这样的大型项目,与小型Hello World示例相比,Emscripten生成的代码的大小开销相应减少.
  • Emscripten最近在缩小代码大小方面做了大量改进.确保使用最新的Emscripten版本.
  • 添加 -Os –closure 1可能会将生成的代码的大小减少10倍.

下面是回答问题的描述 how can this be made more size-efficient


为什么生成如此多的代码?

生成的Webassembly量与写入的C++代码量和该代码的依赖性成正比.依赖于标准库的C++程序取决于比您预期的更多的代码.add()像这样的简单功能......

int add(int x, int y) {
    return x + y;
}
Run Code Online (Sandbox Code Playgroud)

..将生成一个简短的Webassembly函数,如下所示:

(func $add (param $x i32 $y i32) (return i32)
  (get_local 0
   get_local 1
   i32.add))
Run Code Online (Sandbox Code Playgroud)

但一个电话 printf需要有像函数的定义strlen,flockfile,funlockfile,memcpy,fwrite,fputs,__stdio_write,即从需要制作的标准库中的所有函数printf调用.在本机环境中运行的C++程序只能与平台的正确libc链接,但Webassembly需要携带这些库依赖项.

除了用户空间库依赖项之外,生成Webassembly的工具还需要提供处理系统调用的运行时环境.因此,Hello World程序需要具有覆盖系统调用的定义,以分配内存和写入字节.


编译器如何缩小代码大小?

emscripten的创建者和维护者Alon Zakai 在Emscripten中编写了Mozilla Hacks文章收缩Webassembly和Javascript代码大小.我将在这里总结一下这篇文章的要点:

Emscripten最初专注于通过为系统调用实现libc和运行时提供Posix环境,轻松移植现有的C和C++程序.以便利的名义,通常包括比所需更多的代码.

许多运行时都是作为Javascript代码实现的.Emscripten生成在应用程序/库Webassembly代码和Javascript运行时之间来回调用的代码.

应删除从未调用过的代码.在由称为死代码消除的优化处理的编译器中.Emscripten构建所有函数的图形并删除那些从未从main调用的部分.好的,这不是严格正确的,但足以解释这个问题.

但是编译器以前无法为跨越Webassembly和Javascript之间的边界的调用生成那种图形.随着包含wasm-dce工具而改变了.现在,Emscripten可以创建Webassembly和Javascript代码的图形.


Hello World程序的"收缩"限制是多少?

printf是一个通用函数,它对文件描述符进行操作,并且是线程安全的.为printf调用生成的代码几乎都必须存在.

如果您想更多地了解生成的代码,我建议使用Webassembly Studio在线IDE.它提供了一个示例Hello World项目,其中包含一个自述文件,用于生成库代码和运行时Javascript代码.