//! Allocation counting, compiled in only under `--features count`. //! //! The count is the number that matters. It is stable across machines and //! across load, which a wall-clock number on a shared dev box is not, and it is //! what an emitter change actually moves. The timing run answers "is this //! faster here today"; this one answers "does this do less work". //! //! # Why `dhat` rather than a hand-written `GlobalAlloc` //! //! The workspace sets `unsafe_code = "forbid"`, and a `GlobalAlloc` //! implementation cannot be written without `unsafe`. `forbid` is not //! overridable by an `#[allow]`, so a hand-rolled counter would mean this crate //! opting out of the workspace lint block, and that block is meant to be //! identical everywhere. A dependency that is off by default is the cheaper //! trade: `dhat` holds the `unsafe`, and the bench holds none. //! //! It also answers the reason the two measurements are two builds. `dhat`'s //! allocator is real instrumentation and a timing number taken through it would //! be a number about the instrumentation, so `count` is never on in a timing //! run. /// The counting allocator, in place only in a `--features count` build. #[global_allocator] static ALLOC: dhat::Alloc = dhat::Alloc; /// A running profiler, held for as long as measurements are being taken. pub struct Session(dhat::Profiler); impl Session { /// Start counting. /// /// `testing()` keeps `dhat` from writing its JSON output file: the bench /// wants two integers, not a profile to open in a viewer. #[must_use] pub fn start() -> Self { Self(dhat::Profiler::builder().testing().build()) } } /// Allocations and bytes so far in this session. /// /// `total_blocks` is every allocation since the profiler started, which is what /// "how many allocations does rendering this screen take" means. The live and /// peak figures `dhat` also carries are about retention, and a renderer that /// returns a `String` and drops everything else has nothing interesting there. #[must_use] pub fn read() -> (u64, u64) { let stats = dhat::HeapStats::get(); (stats.total_blocks, stats.total_bytes) }