Open frehberg opened 6 years ago
The dynamic allocation example is measuring a whole lot more than just dynamic allocation: string formatting is rather heavy, and I suspect it is pulling in the panicking infrastructure as well.
If you are trying to specifically measure the code size of allocators, I suggest something more targeted, like https://github.com/rustwasm/wee_alloc/blob/master/example/src/lib.rs
You can built that with the ./build.sh
script in this repo. If size classes are disabled, I get a 1,148 bytes binary, and if I enable size classes, then I get a 1,415 bytes binary (after wasm-gc and wasm-opt):
1148 ../target/wasm32-unknown-unknown/release/wee_alloc_example.gc.opt.wasm
1415 ../target/wasm32-unknown-unknown/release/wee_alloc_example.size_classes.gc.opt.wasm
I have the following lib.rs file:
use wasm_bindgen::prelude::*;
use wee_alloc::WeeAlloc;
// Use `wee_alloc` as the global allocator.
#[global_allocator]
static ALLOC: WeeAlloc = WeeAlloc::INIT;
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
#[wasm_bindgen]
pub fn greet(name: &str) {
alert(name);
}
When I compile that using wasm-pack and then inspect the output using twiggy, I get:
Shallow Bytes │ Shallow % │ Item
───────────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1353 ┊ 25.55% ┊ "function names" subsection
1065 ┊ 20.11% ┊ data[0]
580 ┊ 10.95% ┊ <wee_alloc::WeeAlloc as core::alloc::GlobalAlloc>::alloc::h56b2fbb231097050
574 ┊ 10.84% ┊ wee_alloc::alloc_first_fit::hc3745372ad8f8d4e
327 ┊ 6.18% ┊ wee_alloc::WeeAlloc::dealloc_impl::{{closure}}::h92c7acfcf75e2e63
252 ┊ 4.76% ┊ <wee_alloc::size_classes::SizeClassAllocPolicy as wee_alloc::AllocPolicy>::new_cell_for_free_list::h6ef3252c1cc78ab3
176 ┊ 3.32% ┊ <wee_alloc::WeeAlloc as core::alloc::GlobalAlloc>::dealloc::haa7b6f21eac5aae6
121 ┊ 2.29% ┊ <wee_alloc::LargeAllocPolicy as wee_alloc::AllocPolicy>::new_cell_for_free_list::h8d68be1a53220a52
113 ┊ 2.13% ┊ custom section 'producers'
80 ┊ 1.51% ┊ data[1]
57 ┊ 1.08% ┊ __rg_realloc
56 ┊ 1.06% ┊ memcpy
47 ┊ 0.89% ┊ __wbindgen_malloc
35 ┊ 0.66% ┊ import wbg::__wbg_alert_e4f89deb17f7e8ca
35 ┊ 0.66% ┊ __wbindgen_realloc
26 ┊ 0.49% ┊ greet
21 ┊ 0.40% ┊ export "__wbindgen_realloc"
21 ┊ 0.40% ┊ __rust_realloc
20 ┊ 0.38% ┊ export "__wbindgen_malloc"
17 ┊ 0.32% ┊ __rust_alloc
319 ┊ 6.02% ┊ ... and 42 more.
5295 ┊ 100.00% ┊ Σ [62 Total Rows]
Rows 3-8 all appear to be wee_alloc, and it adds up to 2030 bytes. That includes size_classes, but still bigger than the 1.2 KB advertised in the README.
It's still much smaller than the default allocator though.
Probably this ticket can be closed now. The size was related to a bug in Rust-lang, as rust kept dependencies to both, wee-alloc and dlmalloc. It was caused by some hard coded function name for an intrinsic in rust-lang, keeping a dependency to dlmalloc. This caused the Wee-alloc based binary to be even larger than the pure dlmalloc binary.
When building with opt-level = "s"
and then running through wasm-opt -Os
, the size gets smaller. It's hard to tell which symbols are which in the wasm-opt
output, but even just enabling opt-level = "s"
brings the payload down to 1534 bytes. So I guess I just wasn't using opt-level = "s"
earlier.
Summary
Compiling a test-app with different settings (dlmalloc and wee_alloc) the resulting binary sizes of wee_alloc builds are not as small as expected. Benefit is just 3KB, the relation is 25KB for dlmalloc-builds compared to 22KB for wee_alloc-builds with code using simple String-allocation. see
With an application without any dynamic memory allocation, wee_alloc is adding 2500 bytes:
With an application using simple String allocation, wee_alloc is adding ca 21000 bytes, being just 3KB better than dlmalloc.
Steps to Reproduce
git clone https://github.com/frehberg/wasm-dyn-mem.git cd wasm-dyn-mem/rust-bindgen make build print-sizes
Expected Results
Linking against wee_alloc instead of dlmalloc I expected binaries being much more smaller and gaining larger benefit compared to dlmallic. Just, in some cases the binary is larger and the relation is just 22KB vs 25KB Maybe wee_alloc is using some code-patterns that can not be optimized as good as expected