Skip to content

Strange bad performance with [u8; 16] and union feature #379

@JonathanWilbur

Description

@JonathanWilbur

Forgive me if I'm making some sort of amateur mistake here. I know when it comes to profiling, subtle things done wrong can completely bias a result, but I ran these two tests with criterion and it is saying that the SmallVec<[u8; 16]> is about 100x slower than the normal Vec at push().

These are my tests:

fn vec_test() {
    let mut v = Vec::with_capacity(13);
    for i in 0..12 {
        v.push(i);
    }
}

fn smallvec_test() {
    let mut v: SmallVec<[u8; 16]> = SmallVec::new();
    for i in 0..15 {
        v.push(i);
    }
}

fn bench_vec(c: &mut Criterion) {
    let mut group = c.benchmark_group("Vec");
    group.bench_function("Normal", |b| b.iter(|| vec_test()));
    group.bench_function("SmallVec", |b| b.iter(|| smallvec_test()));
    group.finish();
}

However, when I change it to SmallVec<[u8; 15]>, the smallvec is 3x faster than Vec (which is a result that I would expect).

Why would adding that single additional byte make this so slow? I am using the union feature, so I would think that 16 bytes could fit in SmallVec while keeping it the same size as a Vec. Is this a known problem? Am I making some obvious mistake?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions