Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ergonomic way to specify the maximum "for free" capacity (i.e., leverage padding)? #274

Open
NicholasGorski opened this issue Dec 31, 2021 · 1 comment

Comments

@NicholasGorski
Copy link

Often when specifying smallvec, I find that I may as well round up the buffer size to leverage any otherwise-unused padding.

For example, a Vec<u32> takes 24 bytes on my platform. Assuming the union feature is enabled, a SmallVec<[u32; 1]> takes 24 bytes as well...but so does SmallVec<[u32; 4]>. I'd like to always maximize usage of padding bytes since (as far as I can tell) there is no downside. But having to explicitly calculate this is error-prone as these are not typically actually u32, but some small register-sized struct.

Is there a way of performing this rounding implicitly? This might be more of version 2.0 request - e.g. a specified capacity of zero means "default", which means the greater of 1 or whatever fits in padding.

@NicholasGorski NicholasGorski changed the title Ergonomic to specify the maximum "for free" capacity (i.e., leverage padding)? Ergonomic way to specify the maximum "for free" capacity (i.e., leverage padding)? Dec 31, 2021
@dewert99
Copy link

dewert99 commented Mar 15, 2024

This could be add as a type alias but it would require the incomplete, experimental feature generic_const_exprs

#![feature(generic_const_exprs)]

use smallvec::SmallVec; // 1.13.1
use core::any::type_name;
use core::mem::size_of;

pub const fn small_vec_size<T>() -> usize {
    if size_of::<T>() == 0 {
        usize::MAX
    } else {
        size_of::<Box<[T]>>() / size_of::<T>()
    }
}
pub type OptSmallVec<T> = SmallVec<[T; small_vec_size::<T>()]>;

fn main() {
    println!("{}", type_name::<OptSmallVec<()>>());
    // smallvec::SmallVec<[(); usize::MAX]>
    println!("{}", type_name::<OptSmallVec<u8>>());
    // smallvec::SmallVec<[u8; 16]>
    println!("{}", type_name::<OptSmallVec<u32>>());
    // smallvec::SmallVec<[u32; 4]>
    println!("{}", type_name::<OptSmallVec<usize>>());
    // smallvec::SmallVec<[usize; 2]>
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants