如果你在意性能,请不要使用 musl。
Don't use musl if you care about performance

原始链接: https://blog.brokk.ai/dont-use-musl-if-you-care-about-performance/

作者最初因 `musl` 能够构建简单且自包含的 Rust 二进制文件而对其产生兴趣,但在测试后发现了显著的性能问题。与普遍认为 `musl` 仅在极端并发下表现不佳的观点不同,作者发现它在标准的 4 核系统上性能表现极差。 尽管将 `musl` 的默认分配器更换为 `mimalloc` 可以带来一定改善,但仍无法与 `glibc` 持平,速度依然慢了约 26%。进一步调查显示,性能差距不仅源于分配器优化不足,还归咎于 `musl` 核心内存例程的低效。 作者总结认为,虽然 `musl` 对于小型且对性能要求不高的项目尚可接受,但对于高性能应用而言,它就像一把“随时会走火的枪”。因此,作者决定在其对性能敏感的项目 Bifrost 中移除 `musl` 的预构建选项,并指出 `musl` 要么应取消默认分配器,要么应解决其系统性的效率低下问题。

最近关于“如果你在意性能,就不要使用 musl”的 Hacker News 讨论,凸显了注重可移植性的人群与关注执行速度的人群之间的分歧。 musl 的批评者认为,其内存分配器表现不佳,存在全局互斥锁竞争问题,导致多线程应用出现显著瓶颈,从而拖累了整体性能。此外,人们经常指出 musl 对 memcpy 和 memset 等基础例程的实现过于简单,与 glibc 相比会产生可观测的开销。 支持者承认这些缺陷,但坚持认为 musl 在静态链接方面非常便捷,能够简化部署并避免容器环境中的“glibc 依赖地狱”。许多开发者指出,对于他们特定的应用场景(如 I/O 密集型工具),性能损耗通常可以忽略不计。一些人提出了折中方案:利用 musl 的简洁性,同时替换为 mimalloc 等高性能分配器,以缓解最严重的瓶颈。 最终,业界共识认为:虽然 musl 在提升可移植性和减小二进制文件体积方面极具价值,但它通常不适合高并发、对性能要求苛刻的应用,除非配合经过仔细优化的替代方案使用。
相关文章

原文

I've spent most of my career working inside the JVM, with a sidebar of Python. So the first time I hit incompatible libc with containerized Bifrost, and GPT suggested musl as the solution, not only did I jump on it, I moved my other Rust projects to musl as well. Self contained binaries with a single implementation backing them? Yes, please!

Then my colleague Ryan mentioned that musl is known to have a suboptimal allocator, and pointed me to Daniel Raneland's article. Uh-oh. I decided to measure it to see how bad it was.

So, yes: musl's allocator is indeed bad. Terrible, even. And (contrary to some of the articles I've read) not only in high concurrency scenarios; these numbers are from 4 core EC2 VMs, and Bifrost sizes its thread pools accordingly.

This is a really bad footgun to leave loaded for users and honestly, I think musl should ship without an allocator and make you choose one. Then if you choose the really bad one for some reason (maybe the code footprint is really tiny? idk) then that's on you, instead of "oh sorry did you not read the fine print? lol wasn't that a fun surprise!"

But unfortunately "just use mimalloc" [or jemalloc] is not a magic wand that gets musl performance parity with glibc; musl with mimalloc is still 26% slower. So I dug deeper into the two task types that showed the worst regressions.

scan_usages does get some benefit from mimalloc, but remains slower than on glibc. structural_clone_smells on the other hand barely allocates; the difference on musl with and without mimalloc is noise. Yet s_c_s suffers even more, proportionally, from musl than does scan_usages.

It turns out that the allocator isn't the only suboptimal code in musl, and several common memory routines are particularly slow:

I'm going to keep smaller projects where 25% slower doesn't matter (like Hel) musl-only for simplicity—with the addition of mimalloc. But in the spirit of not leaving more loaded footguns around, we're removing musl as an prebuilt option from the much-more-performance-sensitive Bifrost.

联系我们 contact @ memedata.com