Hello guys. I am trying to understand memory usage and stack vs. heap when it comes to performance a bit better. I think I'm aware of the general rule: stack is always faster than heap.
For the particular task I am trying to solve, I have a function that returns a 6-byte buffer, and I need to gather 50 such elements and return them. There are four functions I came up with:
// assume f() is some DB call or whatever
fn example0(f: &dyn Fn() -> [u8; 6]) -> Vec<Vec<u8>> {
let mut result: Vec<Vec<u8>> = vec![];
for i in 0..50 {
let data: [u8; 6] = f();
result.push(data.to_vec());
}
result
}
fn example1(f: &dyn Fn() -> [u8; 6]) -> Vec<Vec<u8>> {
let mut result: Vec<Vec<u8>> = Vec::with_capacity(50);
for i in 0..50 {
let data: [u8; 6] = f();
result.push(data.to_vec());
}
result
}
fn example2(f: &dyn Fn() -> [u8; 6]) -> Vec<[u8; 6]> {
let mut result: Vec<[u8; 6]> = Vec::with_capacity(50);
for i in 0..50 {
let data: [u8; 6] = f();
result.push(data);
}
result
}
fn example3(f: &dyn Fn() -> [u8; 6]) -> [[u8; 6]; 50] {
let mut result: [[u8; 6]; 50] = [[0; 6]; 50];
for i in 0..50 {
let data: [u8; 6] = f();
result[i] = data;
}
result
}
I am pretty sure example0
is the worst, since no size information is known, and a lot of allocations would have to be made.
example1
is probably a bit better since the outer vec knows it has a size of 50, but the inner elements are still not known.
example2
should be pretty decent, since it "knows" that it will have 50 [u8; 6]
Finally, example3
knows exactly how many bytes are needed, so it should be the most efficient.
Am I correct in my understanding? What are the main differences between 2 & 3, considering in both cases all sizes are known at compile time?
9 posts - 6 participants