user986139
user986139

Reputation:

To heap or stack array. A user-defined type conundrum

UPDATE

When designing a mostly short-lived container that isn't big enough to warrant a heap allocation but isn't small enough that move semantics will not make any difference. How should one decide on which way to design the container so that it is performant (size/space is secondary to).

As far as I can see, there are two methods:

Method (A) implement internal data as a pointer and use heap allocation. T* data = new T[]

Method (B) implement stack array data structure. T data[]

I am new to C++ and have been reading up on many articles on SO regarding stack vs heap. This is what I currently gathered...

Method (A)

advantages:

disadvantage:

Method (B)

advantages:

disadvantages:

If for example, given a user designed type that will be used to do a lot of calculations, which means a lot of temporaries. What would be the most performant way?

The heap array's ability to move, and when combined with nullptr the ability to do zero-copy seems to me like it would eliminate any advantage a stack would give, since moving involves only 1 pointer substition vs a medium sized array copy.

Are there factors I've missed or misunderstood? What would one generally need to know in order to decide which method to take?

Can the stack copy arrays of data faster than a heap move/pointer reassignment?

Upvotes: 0

Views: 306

Answers (1)

user395760
user395760

Reputation:

You shouldn't dynamically allocate if you're not sure whether you need it. Speed and space implications aside, it's simply more code to write and get right. Moreover, should some client code need indirection (e.g. to move efficiently, or to save space by omitting data), they can always add this from the outside: std::unique_ptr<ModeratelyLargeType> works fine.

Regarding the specific int24 type:

You should make it a struct containing three uint8_ts or some similar way of getting 24 bits directly into the object. I assume that's what you mean by "stack array". The "advantages" of method A and the corresponding "disadvantages" of method B you list are nonsense:

[A +] No memory allocation until required (can use nullptr on an empty constructor until initialised / assigned)

[B -] Must allocate memory immediately where it's declared.

Method A always needs to allocate a pointer, and the pointer is larger than the actual data (32 or 64 bits vs. 24 bits). Not only does method A use more than twice as much memory when actually used, it uses more memory even when not used. All of this without considering the space overhead of heap allocator metadata.

For completeness I should add, depending on how exactly you implement this, alignment may force the compiler to insert padding, making the structure larger than 24 bits but still no larger than a null pointer (so the above still stands). Likewise, it obviously won't use three quarters of a 32 bit register.

[A +] Possible to make move constructible and move assignable.

[B -] Not possible to move?

Well, you can move the pointer, but that's not more effective than copying three bytes. Again, the pointer is larger than the data it points at.

Upvotes: 2

Related Questions