为性能库制作高效包装器的聪明方法

Smart way to make efficient wrapper for a performance library

假设,我们有一个外部库可以对双精度浮点数数组进行非常快速的计算(大多数时候是多线程的)。为方便起见,我以面向对象的方式编写代码,以便获得对象数组。每个对象都有一个 属性 保存双精度值。使用强大的外部库的简单方法是这样的:

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

但是,这需要时间和额外的内存来保存 temp 数组。有更好的方法吗?

这是一个一般性问题,但我基本上想在 C++ 中解决这个问题。

如果您确定您的 objects 只包含一个 double 数据成员,没有 data-member-adding 基和 virtual 函数 - 检查静态断言 sizeof(*objectArray) == sizeof(double) - 假设您的外部库函数是 out-of-line,您可以将外部库 a double* 传递给 objectArray[0].

如果在 header 中包含库函数的内联,则可能 运行 出现别名问题,应查阅编译器文档以了解选项。

如果你的 objectArray 个元素 只是每个 double,你 will 必须将它们复制到压缩数组中,如果这是外部库所期望的。 (您可能考虑的一个选择是将 double 值保存在数组中,并让更复杂的 objects 存储对数组元素的引用)。

您可以为您的对象使用竞技场策略。基本上我们的对象将只包含一个索引和一个数据领域的句柄。实际数据存储在竞技场中正确的索引处。这样,当您需要创建 double 的向量时,它已经存在于竞技场中。

这只有在您始终知道哪些对象一起处理并且它们几乎总是一起处理的情况下才有效。如果您每次需要 select 需要哪些对象,这不会给您带来任何性能提升(除非对象在数组中始终是连续的)。这也会使常规对象访问速度稍慢一些,因此只有在每次复制值确实是您编程的瓶颈时才有意义。

您的数据结构如下所示:

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]; }
};

您需要更多的代码来确保分配了东西等等,但您明白了。现在,当您需要调用外部库时,您可以直接从 Arena 对象中获取数组。