But the code is not the most efficiency, even though Vec::new do not allocate memory, let foo_default = Foo { data: Vec::new() }; is not zero cost, which I don't really need. But I can't use MaybeUninit, since the replaced data field will be collect.
I tried to use MauallyDrop, but it takes a Foo, while drop only offer a &mut Foo.
So how to write to make this drop function more efficiency?
P.S. the let mut vec = cache.take(); has the same problem
I think it will write some default value to memory, some sort of memset(0, sizeof(foo_default) . So I guess it's more costy than use MaybeUninit::asssume_init. Or do I miss something?
It will create a triple like (1usize, 0usize, 0usize), i.e. "dangling pointer to u8, capacity = 0, length = 0". This is not literally zero-cost, but any other operation around here will be more costly.
then, by design, producing a CONST is guaranteed to be zero-cost (modulo the bitwise-copy of the entity itself).
In this instance, it just so happens that Vec::new() itself is designed to be zero-cost as well; it's basically the same as producing a (1, 0, 0) triplet of usize values.
With it, doing mem::replace(self, DEFAULT_FOO); is thus guaranteed to be as zero-cost as possible: bit-copying the vec and potentially[1] "replacing it with a "NULL vec"[2].
with optimizations this will probably be skipped altogether ↩︎
this is what Vec::new() yields, for what is worth ↩︎
I think it maybe a better way to write a custom function that takes the ownership of Foo, do what you want, then panic when manually drop by setting a special field.
In addition, if you want to collect the instance that going to be dropped by implementing Drop for Foo, you'll face a situation that how to drop collected instance. Memory leak, stack overflow or dead cycle will be the result.