Closed TimDiekmann closed 3 years ago
The main users of shrink
are Vec::shrink_to_fit
and Vec::into_boxed_slice
so let's consider when you would use those. Generally speaking it's only used if:
As such I think it's fine for shrink
to favor saving memory over performance.
FWIW, for the case of a bump allocator, wouldn't a realloc-ing shrink merely use more space, since the old space can't be used?
Not necessarily, if you shrink the latest allocated block, it's possible to actually shrink the used memory.
@Amanieu thank you for reminding me about this!
There are a few pre and postconditions to
shrink
:new_size < layout.size()
,Recently I tried to optimize the
Region
allocator (basically a bump allocator using&mut [u8]
as backend). Implementingalloc
,dealloc
andgrow
is straight forward but how isshrink
supposed to be implemented? There are 3 possible cases, for which all pre-/post conditions still hold. I leave outReallocPlacement
and implementation details like bumping-up and bumping-down, similar cases applies to all of them.new_size == layout.size()
: just return the same pointer, just like the default implementation. This is the trivial case.ptr
is the latest allocated block: It is possible to reduce the used memory by moving thecurrent
-ptr to match the requested size (maybe introducesptr::copy
). It's also possible to simply return the same pointer as passed toshrink
. Both cases are valid; the former is less memory hungry, the latter is faster.else
: As always, returning the same pointer is also valid, but how expected is this behavior?What's the prefered way to implement
shrink
(performance vs memory)? Do we have to specify the behavior ofshrink
? Shouldshrink
be overhauled in it's API in any way?Notes:
realloc
fornew_size < layout.size()
,shrink
a best-effort-method, as other methods likedealloc
has to deal with the returned pointer.