3

我正在编写一个科学计算程序,我最感兴趣的(在正确性之后)是速度。最近我注意到我也需要可读的代码。:)

而不是写

for (int k=0;k!=10;k+=1)
   array[k] = fun(a, k);

我在考虑写

class fun_t {
private:
   type a;
public:
   fun_t(type in) : a(in) {};

   type operator() (int k) {
      ...computation...
   }
};
...
fun_t fun(a);
for (int k=0;k!=10;k+=1)
   array[k] = fun(k);

函数对象样式会和第一个例子一样快吗?我可以期望两者都有相同的内联吗?有没有更好的方法?(请注意,我只是在这里提出这个想法,这不是我的实际代码。)

4

3 回答 3

4

我想繁重的计算是在你的函数内部执行的。相比之下,直接函数调用和成员函数调用之间的差异应该是微不足道的。

于 2012-10-25T11:39:34.170 回答
2

您可以从合理的编译器中获得相同的内联。调用的目的地operator()在编译时是已知的,就像调用fun(a,k).

我看到的区别在于对a. 在函数的情况下fun,您将某些内容作为参数传递 - 如果没有声明,fun则无法查看这是否是 的副本a、对 的引用a或由 构造的其他类型a

在仿函数的情况下fun_t,您复制a一次以构造仿函数。您(名义上)将 a 传递给,然后fun_t*作为访问。一旦所有内容都被内联并且优化器完成后,额外的间接可能会被忽略,但同样可能不会。您必须检查特定情况,可能通过检查编译器发出的指令。thisoperator()athis->a

于 2012-10-25T11:56:57.037 回答
1

您可以通过更改循环结构进行一些小的优化,但这些优化的主要目的不是为了提高速度。

如果你想提高速度,你需要分析。如果fun(a,k)特别是一个缓慢的操作并且每次运行不依赖于其他运行,您应该考虑拆分成线程并在自己的线程上运行每个线程。

有新的 API 将并行而不是串行地对集合进行操作。激动人心的时刻即将到来。

于 2012-10-25T11:41:25.323 回答