diff --git a/mini-alloc/README.md b/mini-alloc/README.md index a7e8e2a..59e84dd 100644 --- a/mini-alloc/README.md +++ b/mini-alloc/README.md @@ -1,41 +1,47 @@ # mini-alloc -`mini-alloc` is a very small bump allocator for wasm32 intended to be used as -the global Rust allocator. It never deallocates memory -- that is, `dealloc` -does nothing. It's suitable for cases where binary size is at a premium and -it's acceptable to leak all allocations. +`mini-alloc` is a small and performant allocator optimized for `wasm32` targets like [Arbitrum Stylus][Stylus]. You can use it in your program as follows. +```rust +#[global_allocator] +static ALLOC: mini_alloc::MiniAlloc = mini_alloc::MiniAlloc::INIT; +``` -One other major limitation: this crate is not thread safe! `MiniAlloc` -implements `Sync` because that is a required of a global allocator, but this is -not a valid implementation of `Sync`, and it must only be used from a single -thread. +## Benchmarks -Also, `core::arch::wasm32::memory_grow` must never be called by any code outside -this crate. +`mini-alloc` implements a minimal bump allocator strategy. It never deallocates memory -- that is, `dealloc` does nothing. It's suitable for cases where binary size is at a premium and it's acceptable to leak all allocations. The simplicity of this model makes it very efficient, as seen in the following benchmarks. -On targets other than wasm32, `MiniAlloc` simply forwards to the allocator from -another crate, `wee_alloc::WeeAlloc`. +| | `MiniAlloc` | [`WeeAlloc`][WeeAlloc] | Std Library | +|--------------|-------------|------------------------|----------------| +| alloc | 333 gas | 721 gas | 516 gas | +| alloc_zeroed | 329 gas | 95 million gas | 48 million gas | -`mini-alloc` uses less ink on -[Stylus](https://github.com/OffchainLabs/stylus-sdk-rs) compared to other -allocators. When running the `edge_cases` test in this crate on Stylus, here are -ink costs (minus the cost of memory expansion) when using `MiniAlloc` vs -`WeeAlloc` and Rust's default allocator. +The benchmarks compare the performance of this crate's `edge_cases` test in the [Stylus VM][StylusVM]. Normal allocations are over **2x** cheaper than when using [`WeeAlloc`][WeeAlloc], a common WASM alternative that this crate defaults to when built for non-WASM targets. +Replacing each instance of `alloc` in the test with `alloc_zeroed` reveals an over **99%** improvement for zero-filled allocations. Unlike [`WeeAlloc`][WeeAlloc] and the standard library, `MiniAlloc` takes advantage of the fact that WASM pages are zero-filled at initialization, and uses fewer of them due to the layout of Rust's memory. -| | MiniAlloc | WeeAlloc | Default | -| ------------- | ------------ | ------------ | ------------ | -| alloc | 3324474 | 7207816 | 5163328 | -| alloc_zeroed | 3288777 | 954023099920 | 484822031511 | +In the above tests we disable memory expansion costs, which unfairly penelize `WeeAlloc` and the standard library due to their increased resource consumption. -`alloc` means `edge_cases` was run as it appears in this crate. `alloc_zeroed` -means the calls to `alloc` were replaced with calls to `alloc_zeroed`. We can -achieve substantial savings in this case because newly expanded memory in WASM -is already zeroed. +## Notice -Use `MiniAlloc` like this: +`MiniAlloc` should not be used in `wasm32` environments that enable the multithreading proposal. Although `MiniAlloc` implements `Sync` since Rust requires it for the global allocator, this crate should not be used in this way. This should not be a concern in [`Stylus`][Stylus]. -```rust -#[global_allocator] -static ALLOC: mini_alloc::MiniAlloc = mini_alloc::MiniAlloc::INIT; -``` +Also, `core::arch::wasm32::memory_grow` must never be called by any code outside this crate. + +On targets other than wasm32, `MiniAlloc` simply forwards to the allocator from another crate, `wee_alloc::WeeAlloc`. + +## License + +© 2023 Offchain Labs, Inc. + +This project is licensed under either of + +- [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) ([licenses/Apache-2.0](../licenses/Apache-2.0)) +- [MIT license](https://opensource.org/licenses/MIT) ([licenses/MIT](../licenses/MIT)) + +at your option. + +The [SPDX](https://spdx.dev) license identifier for this project is `MIT OR Apache-2.0`. + +[Stylus]: https://github.com/OffchainLabs/stylus-sdk-rs +[StylusVM]: https://github.com/OffchainLabs/stylus +[WeeAlloc]: https://github.com/rustwasm/wee_alloc