#[inline(never)] и #[cold] - когда использовать?🔹
#[inline(never)]Изолирует редкий или громоздкий код от горячего пути.
Горячий путь меньше - лучше локальность - больше производительность.
✅ Используй, если:
код вызывается редко.
хочется сократить размер inlined функций;
slow path.
fn some_threaded_algo(rw: &RwLock<Foo>) -> Bar {
let read = rw.read();
match try_do_stuff(&*read) { // may fail with only shared ref
Ok(bar) => bar,
Err(_) => {
drop(read);
slow_path(rw)
}
}
#[inline(never)]
fn slow_path(rw: &RwLock<Foo>) -> Bar {
let mut write = rw.write();
do_stuff(&mut *write) // may not fail with exclusive ref
}🔹
#[cold]Помечает функцию как исключительно редкую.
Позволяет релоцировать код для лучшей производительности горячего кода.
✅ Используй, только если:
вызов происходит <1% случаев;
код отрабатывающий только на разогреве и не используемый позже.
функция вызывается только в исключительных случаях.
⚠️ Не ставь
#[cold], если функция вызывается даже изредка - даже 1–2% уже много.💡 Некоторые функции и макросы, такие как
panic!(), сами по себе уже #[cold], дополнительная аннотация не требуется.Для
slow_path из примера выше можно добавить #[cold], если необходимость в экслюзивном локе это исключительная редкость.Бонус.
Если вам привычны
likely и unlikely, что бы помечать ветки как холодные, они есть в nightly.На stable вы можете легко их реализовать сами - просто сделайте вызов пустой холодной функции.
#[inline(always)]
fn likely(b: bool) -> bool {
if b {
true
} else {
cold_path();
false
}
}
#[inline(always)]
fn unlikely(b: bool) -> bool {
if b {
cold_path();
true
} else {
false
}
}
#[inline(always)]
#[cold]
fn cold_path() {}