Crates.io | ice_code |
lib.rs | ice_code |
version | 0.1.4 |
source | src |
created_at | 2024-02-26 19:16:54.070104 |
updated_at | 2024-02-26 22:24:48.921786 |
description | A macro to mark code paths as cold, allowing the common case to be inlined. |
homepage | https://github.com/zslayton/ice_code |
repository | https://github.com/zslayton/ice_code |
max_upload_size | |
id | 1154050 |
size | 125,571 |
What's cooler than being cool?
Alright alright alright alright alright alright alright alright
This crate provides the ice!
macro, which labels a given block of Rust code as a
"cold path" in the application--one that is rarely executed. This information allows the
compiler to prioritize optimizing the other code paths, leading to better method inlining
behavior and boosting performance in the common case.
Here's an example method that branches into two paths:
/// Returns the length of the provided string as long as it's shorter than 256 bytes.
fn short_str_len(input: &str) -> Result<u8, String> {
if let Ok(short_len) = u8::try_from(input.len()) {
// We expect this path to be taken almost every time
Ok(short_len)
} else {
// Oops, the string is too big. This path will almost never be executed.
//
// The `format!` call below requires a surprising amount of assembly to
// heap-allocate a string, serialize its arguments, and panic if the
// system is out of memory.
//
// Let's mark the code that constructs a nicely formatted error as being
// the cold path--ice code.
ice! {
Err(format!("Input string was {} bytes, which is too long.", input.len()))
}
}
}
pub fn main() {
let result = short_str_len("foobar".repeat(1_000).as_str());
assert!(result.is_err());
}
As this godbolt.org output shows, the happy path's code got inlined into main
while all of the machinery needed to construct an error string has been pushed
somewhere else and is hidden behind a call
instruction.
If you use multiple ice!
invocations in the same method, the mangled anonymous names produced
by the compiler may be difficult for humans to disambiguate. You can add a label to the generated
assembly by using this syntax:
cold! {
// label expression
error_handler => Err(format!("..."))
}
This will produce assembly like the following: