Home
Rust
const Generic Example
Updated Nov 20, 2024
Dot Net Perls
Const generic. Imagine a Rust function that is always called with a special constant value. The compiler could optimize this by inlining the function, but this is not always possible.
With const generics, we can instruct the compiler to create special versions of a function based on a constant. This can allow more compile-time optimizations.
const fn
size_of
Generic
Array example. In Rust, arrays must be specified with a constant size. But we can do this with a const generic argument—this would allow us to reduce code repetition.
fn get_array<const C: usize>() -> [u8; C] { // Return an array of the specified size. let mut result = [0; C]; result[0] = 1; result } fn main() { println!("{:?}", get_array::<5>()); println!("{:?}", get_array::<6>()); }
[1, 0, 0, 0, 0] [1, 0, 0, 0, 0, 0]
Bool example. We specify a const generic method by specifying the "const" type and its name after the function name. Here the bool N is the constant bool type.
Info The test() function can have a true or false constant type. We specify this type when we call test() in main.
Tip In this program, the test_no_generic function does the same thing as the test() function, but it has no generic const type.
fn test<const N: bool>() { if N == true { println!("TRUE"); } else { println!("FALSE"); } } fn test_no_generic(n: bool) { if n { println!("TRUE"); } else { println!("FALSE"); } } fn main() { test::<true>(); test::<false>(); test_no_generic(true); test_no_generic(false); }
TRUE FALSE TRUE FALSE
Performance, const. Can we get a performance boost from using a const generic function in Rust? In this program we the 2 test() functions, and the first uses a const type.
Version 1 This version of the code uses a const generic function. The N bool is always known at compile-time.
Version 2 Here we just use a bool parameter. With inlining the compiler may be able to turn the bool into a constant.
Result Using the const generic function is much faster, as the compiler can optimize away the constant usage in the function.
use std::time::*; fn test<const N: bool>(max: i32) -> i32 { let mut result = 0; for _ in 0..max { for i in 0..max { result += if N == true { 1 } else { 2 }; if max - 2 == i { break; } } } result } fn test_no_generic(n: bool, max: i32) -> i32 { let mut result = 0; for _ in 0..max { for i in 0..max { result += if n == true { 1 } else { 2 }; if max - 2 == i { break; } } } result } fn main() { if let Ok(max) = "100000".parse() { // Ensure bool is not known at compile-time. let is_true = max % 2 == 0; let mut sum1 = 0; let mut sum2 = 0; // Version 1: use const generic function. let t0 = Instant::now(); if is_true { sum1 += test::<true>(max); } else { sum1 += test::<false>(max); } println!("{}", t0.elapsed().as_millis()); // Version 2: use non-generic function. let t1 = Instant::now(); sum2 += test_no_generic(is_true, max); println!("{}", t1.elapsed().as_millis()); println!("{} = {}", sum1, sum2); } }
118 ms (const) 782 ms 1409965408 = 1409965408
Const performance notes. When we create a generic const function, we tell the compiler to generate multiple versions of the function. Each version has constants in it based on the parameter.
So The compiler can generate multiple versions of the code, and optimize each one based on its constants.
And No runtime cost is paid for these compile-time features. This is a true zero-cost abstraction.
Summary. We can use const generic functions to generate multiple copies of functions that are better-optimized. With some code changes, this can improve performance by reducing work at runtime.
Dot Net Perls is a collection of pages with code examples, which are updated to stay current. Programming is an art, and it can be learned from examples.
Donate to this site to help offset the costs of running the server. Sites like this will cease to exist if there is no financial support for them.
Sam Allen is passionate about computer languages, and he maintains 100% of the material available on this website. He hopes it makes the world a nicer place.
This page was last updated on Nov 20, 2024 (edit link).
Home
Changes
© 2007-2025 Sam Allen