Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::dynarray vs std::vector

Tags:

c++

stdvector

C++14 presents std::dynarray:

std::dynarray is a sequence container that encapsulates arrays with a size that is fixed at construction and does not change throughout the lifetime of the object.

std::dynarray must be allocated in run-time as same as std::vector.

So what are the benefits and the usage of std::dynarray while we can use std::vector which is more dynamic (and also re-sizable)?

like image 429
masoud Avatar asked Oct 01 '13 08:10

masoud


People also ask

What is the difference between std::vector and vector?

Difference between std::vector and std::array in C++ As array is fixed size, once initialized can't be resized. Vector occupies more memory. Array is memory efficient data structure. Vector takes more time in accessing elements.

What is the difference between dynamic array and vector?

A vector is a dynamic array, whose size can be increased, whereas THE array size can not be changed. Reserve space can be given for vector, whereas for arrays you cannot give reserved space. A vector is a class whereas an array is a datatype.

Should I use std for vector?

If you need a "dynamic" array, then std::vector is the natural solution. It should in general be the default container for everything. But if you want a statically sized array created at time of compilation (like a C-style array is) but wrapped in a nice C++ object then std::array might be a better choice.

Is std::vector fast?

A std::vector can never be faster than an array, as it has (a pointer to the first element of) an array as one of its data members. But the difference in run-time speed is slim and absent in any non-trivial program. One reason for this myth to persist, are examples that compare raw arrays with mis-used std::vectors.


2 Answers

So what are the benefits and the usage of std::dynarray, when we can use std::vector which is more dynamic (Re-sizable)?

dynarray is smaller and simpler than vector, because it doesn't need to manage separate size and capacity values, and it doesn't need to store an allocator.

However the main performance benefit is intended to come from the fact that implementations are encouraged to allocate dynarray on the stack when possible, avoiding any heap allocation. e.g.

std::dynarray<int> d(5);   // can use stack memory for elements auto p = new std::dynarray<int>(6);  // must use heap memory for elements 

This optimisation requires cooperation from the compiler, it can't be implemented as a pure library type, and the necessary compiler magic has not been implemented and noone is sure how easy it is to do. Because of the lack of implementation experience, at the C++ committee meeting in Chicago last week it was decided to pull std::dynarray from C++14 and to issue a separate array extensions TS (technical specification) document defining std::experimental::dynarray and arrays of runtime bound (ARBs, similar to C99 VLAs.) This means std::dynarray will almost certainly not be in C++14.

like image 69
Jonathan Wakely Avatar answered Sep 19 '22 05:09

Jonathan Wakely


As you said yourself, std::dynarray is for a fixed-size dynamic array. It is not resizable. It's roughly speaking an improvement over new T[N] and over std::unique_ptr<T[]>(new T[N]).

Not needing to resize or manage capacity means you can implement the data structure with less complexity and in less space.

Moreover, std::dynarray is a weird animal that allows the implementation to implement it in different, non-specific ways, e.g. it's possible to put the array on the stack. Calling an allocation function is "optional". You can specify an allocator to construct the elements of the array, but that is not part of the type.

You might also wonder why we need std::dynarray and variable-length arrays. VLAs in C++14 are much more restrictive; they can only be local, automatic variables and offer no way to specify an allocation policy, and of course they don't have a standard container interface.


Some examples from 23.3.4.2 of a "current draft" (take that, Google cache):

explicit dynarray(size_type c); 

Effects: Allocates storage for c elements. May or may not invoke the global operator new.

template <class Alloc> dynarray(size_type c, const Alloc& alloc); 

Effects: Equivalent to the preceding constructors except that each element is constructed with uses-allocator construction.

Whether or not you can use a given allocator to construct the array elements is a global trait:

template struct uses_allocator, Alloc> : true_type { };

Requires: Alloc shall be an Allocator (17.6.3.5). [Note: Specialization of this trait informs other library components that dynarray can be constructed with an allocator, even though it does not have a nested allocator_type.]

Edit: Jonathan Wakely's answer is bound to be far more authoritative and insightful.

like image 38
Kerrek SB Avatar answered Sep 19 '22 05:09

Kerrek SB