Any way to make pushing to `Vec`'s faster?
While working on speeding my project up and looking at flame graphs, I have noticed that a not-insignificant amount(20%-30%) of time is spent in alloc::vec::Vec<T,A>::push. This is weird, because all my Vec's are allocated with Vec::with_capacity and there is no way for them to ever exceed this capacity (the variable that sets the capacity is also used in the loop range). What is even weirder, is that a significant amount of time in alloc::vec::Vec<T,A>::push is spent in core::ptr::write (\~60%)! This is really baffling to me, because simply pushing to vectors, without ever reallocating, takes more time than some compute-heavy parts of the program. What could be the source of this issue? The data which I push to vector is just 32-bit integers(u32), so it should just be written from register to memory in one instruction? And are there any more efficient ways to push into a Vec?
The relevant function in flamegraph:
The flamegraph, a lot of time spent in core::ptr::write
The loop in which the issue occurs:
// Allocation
*data = Vec::with_capacity(length as usize);
// This is from where the data comes from
let precision = UnalignedRWMode::precision_bits(precision);
let mut reader = UnalignedReader::new(src);
for _ in 0..length {
// Reading data and pushes. Reading takes less time than pushing data?
data.push((reader.read_unaligned(precision)? + min) as IndexType);
}
Ok(())
If any more context is needed, here is a link to the file with this function, line 183.
Edit:
compiled in release mode(cargo bench build), issue persist both with and without debug info. Reads themselves are definitely not the issue, while they do relatively complex data decoding, they are counted separately in tmf::unaligned_rw part of flamegraph. They should be by far the largest contributors to execution time(Buffered reads, bit shifts, loops etc.) but are somehow outweight with simple pushes to a Vec.
Edit 2:
The issue us likely found. The flamegraph labels are slightly wrong and may have misattributed the real issue. Calls to core::ptr::write likely come from tmf::unaligned_read, and are the result of it using a BuffReader when it really did not need to(data is decoded from memory, so buffering it makes no sense). Since according to the flamegraph it was such a small overhead it did not even show up, it was last on my list of potential optimizations. So the real issue was hidden by wrong labels, caused by inlining.