On 09/04/13 16:36, Jiří Vyskočil wrote:
Hello,
I need to encapsulate a 3D MultiArray inside another class "GridArray". The reason is that GridArray will have another implementation not using MultiArray and it seems much easier to provide an abstration over MultiArray, than to reimplement its interface for the other implementation.
I need to keep the [][][] operator access to the structure. I created a class like this, but it is slow:
template<class T> class GridArray
{ public: GridArray(int x, int y, int z): _array(boost::extents[x][y][z]) { } boost::multi_array _array; struct SliceRef { struct ColRef { SliceRef &_parent; int _x, _y; ColRef(SliceRef &p, const int x, const int y): _parent(p), _x(x), _y(y) {} T& operator[](const int z) { return _parent._parent._array[_x][_y][z]; } }; GridArray &_parent; int _x; SliceRef(GridArray &p, const int x): _parent(p), _x(x) {} ColRef operator[](const int y) { return ColRef(*this,_x,y); } }; SliceRef operator[](const int x){ return SliceRef(*this,x); } }; I am unable to write a minimal test case - if I compare using multi_array directly vs. using this GridArray class in a simple test program (compiled with -O2), the performance is the same. But the real code shows about 20% slowdown - it's a numerical simulaiton, I create several arrays at the beginning and then do computations with them. The rest of the code hasn't been touched - I only chanded the constructors for the arrays and replaced a header which contained some typedefs with a header containing this class.
Do you have any idea what might be going on? Is there a better way to write an interface for successive [] operators?
Remember that those are references, so you're actually doing
*(_parent->_parent->array)[_x][_y][z].
Some compilers might not be able to avoid the redundant loads here.
You could put SliceRef by value in ColRef for starters. You can also try
to put GridArray