In my program there is some frequently used data type with trivial fields
struct Element {
Element() noexcept : x( 0 ), y( 0 ), z( 0 ) {}
float x, y, z;
};
and also there are many pieces of code taking vectors of Element
s, e.g.
void foo( std::vector<Element> & es );
So it would be very complicated to introduce radical changes in Element
(like changing its default constructor) or rewriting all these pieces to replace std::vector
with something else.
And I have some performance-critical place where a vector of Element
s must be created, filled and passed to foo
:
std::vector<Element> es;
// resize is necessary only to allocate the storage, all values will be rewritten in the parallel region later
es.resize( N );
// perform computation of all values in the vector in parallel for best performance
tbb::parallel_for( tbb::blocked_range<size_t>( 0, es.size() ),
[&]( const tbb::blocked_range<size_t> & range ) {
for ( size_t i = range.begin(); i < range.end(); ++i ) {
...
es[i] = ...
}
}
…
foo( es );
What I observe is that es.resize
takes considerable time for huge N
because it not only allocates the memory, but also default initializes every element, which is not necessary in my case.
Is there a way to increase the size of the vector without initializing its elements, which will be all initialized later? Something like std::make_unique_for_overwrite
available for unique_ptrs.
reserve
, but to use that you have to add elements into the vector usingpush_back
or similar functions. – Bedrailstd::unique_ptr<Element[]>
. FYIstd::string
in C++23 getsstd::string::resize_and_overwrite()
for such purposes. IDK whystd::vector<T>
does not. – Robombemplace_back()
would be the preferred choice – Guajardovector
. Since you know exactly how many elements you need memory for, allocate a byte array of that size, and then useplacement-new
orstd::construct_at()
to construct the actual elements in it where needed. – Guajardoemplace_back
with the OP's type as is: coliru.stacked-crooked.com/a/1aec8b768427b696. If you useemplace_back({1, 2, 3})
instead it will work butpush_back
will do the same thing. – Bedrail