How to cache a vector's capacity?

You don't need any unsafe code to reuse the buffer. There's a feature in the standard library that can be exploited for this purpose: Vec iteration is specialized so that if you consume a Vec and produce a Vec, the allocation is reused if possible, even if the type is different.

Thus, you can change the lifetime to 'a by a dummy map(), as long as the len() of the vector is 0 when you do it:

struct ShortNamePrinter {
    cache_vec: Vec<&'static str>,
    node: Node,
}

...

let mut results = mem::take(&mut self.cache_vec)
    .into_iter()
    .map(|_| -> &str { unreachable!() })
    .collect();

Then put it back in the cache the same way:

results.clear();
self.cache_vec = results
    .into_iter()
    .map(|_| -> &'static str { unreachable!() })
    .collect();

In this playground program I've modified the original code to use this technique. Debug prints show that the allocation is reused after it is created the first time:

[src/main.rs:28] self.cache_vec.as_ptr() = 0x0000000000000008
[src/main.rs:28] self.cache_vec.as_ptr() = 0x000055d9d4837a60
[src/main.rs:28] self.cache_vec.as_ptr() = 0x000055d9d4837a60
[src/main.rs:28] self.cache_vec.as_ptr() = 0x000055d9d4837a60
[src/main.rs:28] self.cache_vec.as_ptr() = 0x000055d9d4837a60
13 Likes