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

Performance Degradation with AnyValue Enum #1903

Open
lalitb opened this issue Jul 2, 2024 · 2 comments · May be fixed by #1913
Open

Performance Degradation with AnyValue Enum #1903

lalitb opened this issue Jul 2, 2024 · 2 comments · May be fixed by #1913
Assignees

Comments

@lalitb
Copy link
Member

lalitb commented Jul 2, 2024

As discussed in linked issue, There is a noticeable performance degradation when using the AnyValue enum compared to the Value enum. This needs to be investigated further.

Originally posted by @cijothomas in #1901 (comment)

@lalitb lalitb changed the title Performance Degradation in AnyValue Enum Performance Degradation with AnyValue Enum Jul 2, 2024
@lalitb lalitb self-assigned this Jul 2, 2024
@utpilla
Copy link
Contributor

utpilla commented Jul 3, 2024

AnyValue enum has bigger variants than Value enum. To test our hypothesis of enum size affecting the creation time, I did some benchmarking for the enum creation with varying sizes of enum and I found that it takes longer to create enums as their size grows (almost linearly).

Benchmark Code
use std::collections::HashMap;

use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn criterion_benchmark(c: &mut Criterion) {
    attributes_creation(c);
}

fn attributes_creation(c: &mut Criterion) {
    c.bench_function("SmallEnum", |b| {
        b.iter(|| {
            let _v = black_box(SmallEnum::Int(10));
        });
    });

    c.bench_function("MediumEnum", |b| {
        b.iter(|| {
            let _v = black_box(MediumEnum::Int(10));
        });
    });

    c.bench_function("BigEnum", |b| {
        b.iter(|| {
            let _v = black_box(BigEnum::Int(10));
        });
    });

    c.bench_function("BiggerEnum", |b| {
        b.iter(|| {
            let _v = black_box(BiggerEnum::Int(10));
        });
    });
}


// Size is 8 bytes
pub enum SmallEnum {
    /// An integer value
    Int(usize),
}

// Size is 24 bytes
pub enum MediumEnum {
    /// An integer value
    Int(usize),
    Vector(Vec<usize>),
}

// Size is 48 bytes
pub enum BigEnum {
    /// An integer value
    Int(usize),
    Map(HashMap<String, usize>),
}

// Size is 96 bytes
pub enum BiggerEnum {
    /// An integer value
    Int(usize),
    Map((HashMap<String, usize>, HashMap<String, usize>)),
}

criterion_group!(benches, criterion_benchmark);

criterion_main!(benches);

Benchmark Results:

Enum Creation time
Small Enum (8 bytes) 167.97 ps
Medium Enum (24 bytes) 470.03 ps
Big Enum (48 bytes) 933.75 ps
Bigger Enum (96 bytes) 1.9512 ns

@lalitb lalitb linked a pull request Jul 8, 2024 that will close this issue
4 tasks
@lalitb
Copy link
Member Author

lalitb commented Jul 8, 2024

Thanks @utpilla, this also explain the improvement observed by box'ing non-primitive/complex types within AnyValue, as that reduces the effective size of the enum. Have created #1913 as potential fix for it.

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

Successfully merging a pull request may close this issue.

2 participants