1

For a performance oriented library, we currently employ std::arrays, whose length are depending on the problem.

As a result, the whole code is templated with <int N1, int N2>, where N_1,N_2 are the unrelated length of the arrays being used, leading to long and memory intensive compilation, for probably little performance gain.

How can we replace in the most modern way these arrays, given that:

  • Size of the array are known at run time
  • These array might contain PODs and custom class alike
  • We loop over these arrays a LOT
  • Length of these arrays are between 0 and 5, so they are kind of small
  • These arrays don't get copied around, and destroyed at the end of the code
  • C++17

My first idea was to wrap in a struct a unique_ptr<T[]>, with T templated, equipped with all the arrays methods we use in the code, to minimise refactoring.

My questions are:

  • What would be the drawback of my initial idea?
  • Is there any better/more modern way to achieve that?
3
  • Have you tried boost static vector? Commented Aug 11, 2020 at 5:47
  • probably would avoid to have the extra dependency if possible Commented Aug 11, 2020 at 5:52
  • You can use static vector as an example of how to achieve what you are looking for. As to being a dependency, it is only a header file -- the entire implementation is contained there. Commented Aug 11, 2020 at 5:54

3 Answers 3

1

If allocations in your code are performed ones, startup time of the application doesn't matter, and the size of the biggest size of the vector are known, than maybe a simple solution with std::vector and reserve will do.

But it seems what you need is a kind of Small String Optimization (SSO) that is used for std::string. The technique allows to store data on the stack if the size of the data is small enough to fit into the size of the class (minus the size of the flagging members), representing the string. Generally this is a common problem and it has been addressed by many people before.

There are several options:

  1. use std::basic_string if your types are char-like.
  2. [Dependency] Use boost small_vector
  3. [Dependency] Use folly small_vector
  4. Write your own implementation based on std::array (but do not derive from std::array, just use it in your class), but make it reserve more memory.
  5. Write your own vector with SSO.

The choice also depends on the size of the objects you want to store. Variants 1,2,3 will work for a few PODs well, but may need allocation for bigger sizes. Variant 4 may be the easiest to implement and it will work with PODs and classes alike, but it will always need extra memory. Also this is like an std::vector with reserve, except for that data will be allocated on the stack, not heap. Variant 5 may be an overkill, probably you don't need it to be that versatile.

Sign up to request clarification or add additional context in comments.

Comments

1

Length of these arrays are between 0 and 5

A good solution is to use an automatic array of length 5 for each. The potentially lost memory of 0-4 integers is likely to be insignificant compared to dynamic allocation overhead.

A potentially even better alternative can be a custom allocator for std::vector, depending on usage pattern. But those are a lot of work.

Comments

0

You wrote in your question that sizes are known in runtime, in that case, I do not understand how your previous templated solutions worked since N1 and N2 should be known in compile-time for it to work.

Leaving that aside, you can use fixed-sized vectors (std::array) as described in: C++ vector of fixed size vecors

2 Comments

the initial library was meant to be instantiated for specific values of N1 and N2 in C++. Then, when adapting it to the usage of the client code in C#, we felt that N1 and N2 should have been dynamic, and to be quick, we simply compiled all possible 6^2 cases, and via a switch, dynamically chose the right one. Now it is perhaps time to amend that.
I understand. If you are using C++11 and behind you can just use std::vector in this case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.