perf(server): 用 mimalloc 替换系统全局分配器
多线程高频小对象分配场景下,mimalloc 吞吐显著优于系统 malloc,且对全静态 musl 链接友好(生产 Docker 镜像即 musl 目标)。选 mimalloc 而非 jemalloc: 本项目生产 server 是全静态 musl 二进制,jemalloc 在 musl 上有 pthread_getname_np (musl<1.2.3)/unprefixed-malloc 符号冲突的已知坑。 cfg 双门控(与项目双目标编译约定一致): - feature=server:分配器只服务端二进制需要 - not(wasm32):mimalloc_rust 在 wasm32 上无法编译(Issue #76),前端走默认分配器 mimalloc 声明为 optional + 经 server feature 启用,与 argon2/uuid 等 server-only 依赖同栏位。验证:server native + WASM 双目标编译通过 + clippy 零告警。 musl 目标受本机无 musl-gcc 限制,需 Docker 内构建验证(同 zenwebp 等任何 C 依赖)。
This commit is contained in:
parent
8c907e4c67
commit
5b183007a7
@ -129,6 +129,8 @@ Dioxus 0.7 fullstack project with **two independent gates** — the most common
|
||||
|
||||
**Shared types that compile on both targets**: bridges like `src/tiptap_bridge.rs` and `src/codemirror_bridge.rs` keep shared structs (e.g. `UploadsInFlight`, `SqlSchema`/`SqlTable`) outside cfg gates, while wasm-bindgen externs + `EditorHandle` live in inner `#[cfg(target_arch = "wasm32")] mod wasm`. Similarly `src/sysinfo_sampler.rs` exposes `SystemSnapshot` on both targets but gates the actual sampler + `RwLock` behind `server`.
|
||||
|
||||
**Global allocator (mimalloc)**: `src/main.rs` registers `#[global_allocator] static GLOBAL: mimalloc::MiMalloc` gated with `#[cfg(all(feature = "server", not(target_arch = "wasm32")))]`. Both gates are load-bearing: `mimalloc` is `optional = true` enabled via the `server` feature, and the `mimalloc_rust` crate does not compile on `wasm32` (Issue #76), so the WASM frontend must fall back to the default allocator. Do not delete either cfg — removing the `not(wasm32)` gate breaks the frontend bundle, removing the `server` gate pulls mimalloc into the WASM target. Chosen over jemalloc because the production server is a fully-static musl binary (Dockerfile), and jemalloc has known musl build pitfalls (`pthread_getname_np` for musl <1.2.3, `unprefixed-malloc` symbol conflicts); mimalloc links cleanly into musl/glibc/FreeBSD.
|
||||
|
||||
## Dual API Architecture
|
||||
|
||||
The server exposes two distinct API patterns:
|
||||
|
||||
19
Cargo.lock
generated
19
Cargo.lock
generated
@ -2644,6 +2644,15 @@ version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
||||
|
||||
[[package]]
|
||||
name = "libmimalloc-sys"
|
||||
version = "0.1.49"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a45a52f43e1c16f667ccfe4dd8c85b7f7c204fd5e3bf46c5b0db9a5c3c0b8e9"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.18"
|
||||
@ -2868,6 +2877,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mimalloc"
|
||||
version = "0.1.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d4139bb28d14ad1facf21d5eb8825051b326e172d216b39f6d31df53cc97862"
|
||||
dependencies = [
|
||||
"libmimalloc-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
@ -5496,6 +5514,7 @@ dependencies = [
|
||||
"js-sys",
|
||||
"lol_html",
|
||||
"md-5 0.10.6",
|
||||
"mimalloc",
|
||||
"moka",
|
||||
"pinyin",
|
||||
"pulldown-cmark",
|
||||
|
||||
@ -54,6 +54,10 @@ bollard = { version = "0.21", optional = true }
|
||||
# 把 mpsc::Receiver 包成 Stream,供 axum SSE handler 使用。
|
||||
# axum::response::sse::{Sse,KeepAlive,Event} 随 axum 0.8 自带,无需额外 dep。
|
||||
tokio-stream = { version = "0.1", features = ["sync"], optional = true }
|
||||
# 全局分配器:用 mimalloc 替换系统 malloc。多线程高频小对象分配吞吐显著提升,
|
||||
# 且对全静态 musl 链接友好(生产 Docker 镜像即 musl 目标)。
|
||||
# server-only:经 server feature 启用;WASM 前端构建不编译(见 main.rs cfg 门控)。
|
||||
mimalloc = { version = "0.1", optional = true }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
web-sys = { version = "0.3", features = ["Document", "Window", "Storage", "Element", "HtmlElement", "DomTokenList", "MediaQueryList", "HtmlImageElement", "MouseEvent", "KeyboardEvent", "Node", "EventTarget", "Navigator", "File", "FileList", "FormData", "Request", "RequestInit", "Response", "Headers", "ClipboardEvent", "DataTransfer", "HtmlInputElement", "EventSource", "MessageEvent"] }
|
||||
@ -114,4 +118,5 @@ server = [
|
||||
"dep:bytes",
|
||||
"dep:bollard",
|
||||
"dep:tokio-stream",
|
||||
"dep:mimalloc",
|
||||
]
|
||||
|
||||
10
src/main.rs
10
src/main.rs
@ -9,6 +9,16 @@
|
||||
//! 当未启用 `server` feature(例如编译为 WASM 前端)时,
|
||||
//! 仅调用 `dioxus::launch` 启动客户端应用。
|
||||
|
||||
// 全局内存分配器:mimalloc。
|
||||
// 多线程高频小对象分配场景下吞吐显著优于系统 malloc,且对全静态 musl 链接友好。
|
||||
// cfg 门控(与项目「双目标编译」约定一致):
|
||||
// - feature = "server":分配器只服务端二进制需要。
|
||||
// - not(wasm32):mimalloc_rust 在 wasm32 上无法编译(mimalloc_rust Issue #76),
|
||||
// WASM 前端走默认分配器。两个门控同时满足才注册。
|
||||
#[cfg(all(feature = "server", not(target_arch = "wasm32")))]
|
||||
#[global_allocator]
|
||||
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||
|
||||
// 业务模块
|
||||
mod api;
|
||||
mod auth;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user