1

Suppose, we have an external library that can do calculations very fast (most of the times multithreaded) on an array of double precision floating point numbers. For convenience, I write my code in an object oriented way so I get an array of objects. Each object has a property holding a double value. The naive approach to make use of the powerful external library is something like this:

double temp[N];
for i from 1 to N
   temp[i] = objectArray[i].property;
end

However, this takes time and additional memory to hold the temp array. Is there a better way to do that?

It is a general question, but I basically want to this in C++.

Zoltán Csáti
  • 679
  • 5
  • 17
  • 1
    If your library performs the algorithm on an array and _only_ an array, then this is only way. If your library can perform it in another way, then we would need to know a bit more about this library. – Unda Apr 26 '16 at 07:23
  • There are a couple of options I can think of: 1. Hold a double[] member next to you objectArray and make sure they are always synchronized. 2. A better option is to replace your double property with a double* that points into a double[]. That will spare you writing the synchronization code – Uri Brecher Apr 26 '16 at 07:36
  • Without knowing the library `API` its hard to come up with suggestions. This is why the `STL` style of interface is so powerful in that they generalized the concept of pointers as *iterators*. If your library were to accept *iterators* this would be much easier. Is there anything like that in the `API`? – Galik Apr 26 '16 at 07:58
  • @Galik "If your library were to accept iterators this would be much easier." How would it be easier? Could you explain me briefly? I am new to C++. – Zoltán Csáti Apr 26 '16 at 08:28
  • @ZoltánCsáti Then you could use the algorithm with iterators from your object array. Those iterators would return the double value with their `operator*`. – Unda Apr 26 '16 at 08:37
  • @Unda And would it generate a significant overhead? – Zoltán Csáti Apr 26 '16 at 08:44
  • @ZoltánCsáti Well I don't know that, you're gonna have to test it yourself to see if it fits your needs well enough. But as Galik said, iterators are heavily used by the standard library algorithms, so it can't be a bad design. One sure thing is that you'd definitely get rid of creating a temporary array. – Unda Apr 26 '16 at 08:56
  • @Unda Thank you. Unfortunately, I cannot accept your answer, since it's a comment. – Zoltán Csáti Apr 26 '16 at 09:02
  • @ZoltánCsáti You could write an iterator to move between the specific member of your array objects and pass that to such an interface. There should be zero overhead for an iterator like this. – Galik Apr 26 '16 at 09:30

2 Answers2

2

If you're sure your objects only contain a double data member, no data-member-adding bases and no virtual functions - check with a static assertion that sizeof(*objectArray) == sizeof(double) - and assuming your external library function is out-of-line, you can just pass the external library a double* to objectArray[0].

If the library function's inline in a header you include, you may run into aliasing issues and should consult your compiler docs for options.

If your objectArray elements don't just hold a double each, you will have to copy them into a compacted array if that's what the external library expects. (One option you might consider is keeping the double values in an array, and having your more complex objects store references to array elements).

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • My `objectArray` contains other basic data types too and objects of other classes via compositions. What do you mean a compacted array? So do you recommend storing that double array in a property of a class? – Zoltán Csáti Apr 26 '16 at 08:08
  • @ZoltánCsáti: by "compacted array" I was just emphasising the elements-contiguous-in-memory aspect of an array. If you're only creating the array so the library can be applied to it then extracting the elements back into the `objectArray` elements, there's no obvious value in *"storing that double array in a property of a class"*. If you find yourself wanting to treat the array as an object and invoke operations on it - then you might bother to create a class storing or managing the array. Sorry if this doesn't help - it's the balance of needs that determines the best choice. – Tony Delroy Apr 26 '16 at 09:26
  • " If you're only creating the array so the library can be applied to it". Yes, that's only what I need. So if I understand it well, you say 1) don't store that double array in a property - it has no use, 2) as I don't want to make any operations on that array (just needed to pass it to the existing library), use my naive approach seen in my question. – Zoltán Csáti Apr 26 '16 at 09:48
  • @ZoltánCsáti: sounds like the last paragraph of my answer applied - you can either 1) copy them like in your question, or 2) have an array of double sitting there in advance, and directly manipulate the values in it from the `objectArray` objects. To support 2), the `objectArray` elements need some way to know which `double` in the array they control - a reference, pointer, or even a pointer to the start of the array and an index number. – Tony Delroy Apr 26 '16 at 09:55
  • I really like your second method. I will do so. – Zoltán Csáti Apr 26 '16 at 10:34
1

You can use an arena strategy for your objects. Basically our object would contain only a index and a handle to the data arena. The actual data is stored in the arena at the right index. This way when you need to create the vector of double it already exists inside the arena.

This only works if you always know which objects are processed together, and they are almost always processed together. If you need to select each time which objects you need this will not give you any performance boost (unless the objects are always contiguous in the arrays). This also makes regular object access a little bit slower, so it makes sense only if the copying values each time is really the bottleneck in you program.

Your data structures would look like:

class Arena {
   vector<double> propertyX;
   vector<double> propertyY;
   int next_index;
};

class MyObject {
  int index;
  Arena& arena
  MyObject(Arena& arena_ref): arena(arena_ref) { index = arena.next_index++; }
  double getX() { return arena.propertyX[index]; }
};

You need a bit more code to make sure things are allocated and such, but you get the idea. Now when you need to call the external library you get the arrays directly from the Arena object.

Sorin
  • 11,863
  • 22
  • 26