On 19.3.2012 18:28, Szymon Gatner wrote:
Erm, why wouldn't it be a good idea?
Because one would normally just return a function-local vector by value which is much cheaper (with move semantics) then heap allocation of a container + 2 x shared_ptr construction.
Moreover, as vector is returned wrapped inside a shared_container_iterator (well, a pair of those) one may pass it directly to Boost.Range or Boost.Foreach (yep, std::pair supported) without spending too much time thinking when and how to allocate and release memory as shared_ptr does that for you.
All well supported also with just returning a container by value.
I don't really know why you should feel bad about allocating a vector from heap as std::allocator will use heap anyway.
This way you get 2 heap allocations + shared_ptr<> construction as opposed to just internal allocation of vector (using allocator). This is especially bad if returned vector turns out to be empty. In that case vector might not do allocation at all so vector creation and return are practically free.
Well, obviously if your compiler has good and guaranteed move semantics along with return value optimizations and you're extermely speed oriented in every way, that's your way to go. You don't have to use everything that library has to offer to you :) The same goes with every choice, whether to use raw pointers (fast, but possibly allocation troubles) or some smart pointer (a small speed penalty, but carefree usage) etc.; It all depends. I must say, that personally I'm not really into returning anything except pod types and trivial things by value. Naturally it happens, strings for an example. Nevertheless, I think it's meaningless to operate on such a low level where you calculate each and every one of your allocations and construtions in a place that they don't usally really matter. (Say, you do a million operations per function call - The first place to look for improvement wouldn't be the few constructions outside the actual and heavyweight loop.) Naturally, if your vector contains only a dozen values the return type is a good question. On the other hand, it's again meaningless if you call your function a couple of times. How about if you call it a million times? I think a small refactoring could be in place etc. I think you get what I mean ;-)
If I'd had to optimize (as in Optimize, not some needless micro optimizations) some vector / array related operation, I think I'd forget any std container, let alone shared_ptr, in the first place...
Interesting. What would you use instead of a vector + specfic allocator when "Optimizing"? Continuous block of memory is rather hard to beat in terms of data processing speed.
Well, I suppose as vectors are pretty much guaranteed to have a contiguous memory allocation and if your platform and compiler is able to use hardware speedups it could work; especially DSP platforms have many loop related tricks that allow certain things to be executed in parallel + the usual (unrolling etc.) tricks. However, this gets too much off the track here. So, my answer final answer is to not use things just because they exist but only if they provide something that is useful for you. What works for me might not work for you as seen here.. -- Pekka