c++ - 减少 Wasm 文件大小(libc、优化、emscripten)
问题描述
所以,我对 Emscripten 做了很多实验。我注意到的是,正在使用的 musl-libc 非常巨大……就像,非常巨大。一个简单的“你好,世界!” 打印应用程序远高于 10kb ......这是迄今为止不实用的。
现在我怎样才能减少这个?到目前为止,我认为我可以使用-Os
and --closure 1
。但后者仅真正适用于 JavaScript,因此不会影响 Wasm 输出。
我还可以做些什么?使用不同的 libc 实现,也许?我查看了 uClibc 和 Dietlibc 以及 Metallic。我还考虑寻找一个便宜的 - 文件大小方面的 - deflate 函数,这样我就可以传输 Wasm 二进制文件的 gzip 压缩版本。但到目前为止,这就是我所得到的。
有什么建议么?我最后一次尝试是:
emcc test.cpp -o test.wasm -s WASM=1 -Os --closure 1
哪里test.cpp
只是一个printf("Hello, world");
.
解决方案
简单的回答:如果您关心二进制大小,请不要使用printf()
,请考虑使用puts()
.
在我的实验中,printf()
“Hello world”的版本高达 13KB,而puts()
版本只有 2KB。
您说“ A simple "Hello, World!" printing app
”,但从更广泛的角度来看实际上并不正确,因为printf()
就二进制大小而言,它是 C 标准库中最大的部分。实际上,我有点惊讶他们设法将其减少到 13KB。这主要是因为%
格式。不仅要printf()
处理简单的格式,例如%c
,%d
和%ld
,而且还必须处理复杂的格式,例如%4.2f
, %+.0e
,%E
和%*d
.
除了 Web 应用程序之外,这是嵌入式系统中的常见问题,您应该静态链接到 stdlib,并且可用的程序内存大小通常小至 10kb。只需谷歌“嵌入式系统中的 printf 大小”,您就会很容易看到 printf() 周围的很多仇恨以及为减小它的大小所做的很多努力。
像 uClibc 和 Dietlibc 这样切换 stdlib 并没有多大帮助,因为它们仍然是 POSIX 系统的库,它实现了 printf() 的完整规范。您应该寻找用于裸机嵌入式系统的标准库,例如 newlib-nano,它实现了 printf() 规范的子集以减小二进制大小。此外,我不认为为 Emscripten 切换 stdlib 几乎是一项不可能的工作,因为 Emscripten 在他们的用例中使用了经过大量破解的 musl-libc 版本。
推荐阅读
- php - Auth()::user() 在 laravel 的多重身份验证中不起作用
- python - ROS 相机校准器错误输出
- python - 从函数更改为类时出现 self.attribute 错误
- javascript - 数字的 JavaScript
- android - RangeError(索引):无效值:有效值范围为空:0同时从rest api获取数据
- javascript - axios如何在没有FormData的情况下发送对象内部的文件?
- c++ - 无法使用 conan-center 配方中的 libc++ 从源代码构建 QT。(qglobal.h:45:12:致命错误:找不到“type_traits”文件)
- delphi - TbannerAd 不展示广告
- c# - 使用依赖注入如何访问服务内类中的方法?
- azure-devops - 逻辑应用:在 ARM 模板中传递动态订阅 ID 和资源组名称