Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return static vector by reference is slow

I was setting up a cache to draw some shapes. My approach was as following:

I created a class OrbitCacheManager.h that looked like this:

#ifndef OrbitCacheManager_h
#define OrbitCacheManager_h
#include <vector>
#include "cache_0_0.h"
#include "cache_1_0.h"
// many more includes

namespace Core {

   class OrbitCacheManager
   {
   public:
        static std::pair<float,float> getValue(const std::pair<int,int>& type, float phase, float param)
        {
            auto cache = getCacheData(type);
            // interpolate values based on phase and param
            return calculated_value;
        }
   private:
        static std::vector<std::pair<float,float>>& getCacheData(const std::pair<int,int>& type)
        {
            if (type.first == 0 && type.second == 0) return cache_0_0::values;
            if (type.first == 1 && type.second == 0) return cache_1_0::values;
            // etc
        }

The cache files look like this:

cache_0_0.h:

#ifndef cache_0_0_h
#define cache_0_0_h 
#include <vector>
namespace Core {
class cache_0_0{
public:
    static std::vector<std::pair<float,float>> values;
};
};
#endif

cache_0_0.cpp:

#include "cache_0_0.h"
using namespace Core;
std::vector<std::pair<float,float>> cache_0_0::values = {
{ 0.000000, 1.000000 },     { 0.062791, 0.998027 }, // etc

This was ment to be run like this:

for (some phase range) {
    auto v = OrbitCacheManager::getValue(type, phase, param);
    // do something with v
}

This approach turn out really slow, the profiler showed lots of CPU peaks and the UI was really laggy.

When I refactored the getCacheData method in OrbitCacheManager.h to this:

static std::vector<std::pair<float,float>>* getCacheData(const std::pair<int,int>& type) 
{
    if (type.first == 0 && type.second == 0) return &(cache_0_0::values);

Everything started working as expected.

My question is, why did that change increased speed so dramatically?

I'am using clang c++11 on IOS

like image 590
andrés Avatar asked Dec 04 '18 15:12

andrés


People also ask

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.

Does vector takes more time than array?

Vector take more time in accessing the elements, whereas the contiguous property of Array makes them highly efficient for accessing the elements.

How much slower are vectors than arrays?

The time difference is 0.333 seconds. Or a difference of 0.000000000333 per array access. Assuming a 2.33 GHz Processor like mine that's 0.7 instruction pipeline stages per array accesses. So the vector looks like it is using one extra instruction per accesses.


1 Answers

You may be returning it by reference, but you are storing in another object, hence still doing a costly copy:

 auto& cache = getCacheData(type);

You should add the & everywhere you return by reference and expect to keep a reference and not a copy.

like image 152
Matthieu Brucher Avatar answered Oct 18 '22 02:10

Matthieu Brucher