Why is shrink_to_fit non-binding?

2019-02-12 03:48发布

问题:

The C++0x FCD states in 23.3.6.2 vector capacity:

void shrink_to_fit();

Remarks: shrink_to_fit is a non-binding request to reduce capacity() to size(). [Note: The request is non-binding to allow latitude for implementation-specific optimizations. —end note]

What optimizations are intended to be allowed?

回答1:

This is quite a strained out, but:

Consider vector's allocator that could only allocate memory with, say, 4 KB granularity. Then it wouldn't make sense to reallocate memory if a vector had capacity of 4096 and size of 4095 as this wouldn't conserve memory, yet waste some CPU time for copying elements.



回答2:

The rounding ideas are indeed relevant, but rather indirectly. The question is "what optimizations are intended to be allowed." That's making some assumptions about the standardization process wrt. optimizations. In general, the intent is to allow all non-observable optimizations and then some - such as copy elision where the not-calling of the copy ctor is observable. In this case, capacity() != size() might be an observable effect of an optimization, and the standard allows it.

As for the reasons to add this latitude, I could also imagine ignoring a shrink request when capacity() is only 101% of size() - too little gains. There will never be a single precise reason, as the LWG consists of many people with many viewpoints. There just is (was) enough of a consensus that there are sufficient extra optimization opportunities created by granting this freedom.



回答3:

While is it already special, vector <bool> has to allocate in blocks of size 8. I also know some people are working on getting malloc to return the 'true size' of any allocated blocks, so if an allocated block would have introduced unavoidable waste, instead the vector usefully uses the space.

As we move to 64-bit OSes, memory space suddenly becomes (famous last words) larger than anyone will ever get close to filling, so it becomes much more reasonable to allocate large blocks of virtual memory and fill them whenever. Moving objects around is expensive, and in practice a waste of time, as we are not moving things because physical memory is limited, just from one virtual place to another!