Reputation: 563
I'm writing a program for scientific computing and my foremost interest (after correctness) is speed. Recently I have noticed that I need readable code too. :)
Instead of writing
for (int k=0;k!=10;k+=1)
array[k] = fun(a, k);
I'm considering writing
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);
Will the function object style be as fast as the first example? Can I expect the same inlinings in both? Is there a better a way? (Note that I'm only presenting the idea here, this is not my actual code.)
Upvotes: 3
Views: 1115
Reputation: 279255
You can expect the same inlinings from a reasonable compiler. The destination of the call to operator()
is known at compile-time just like the call to fun(a,k)
.
The difference I see is in the access to a
. In the case of the function fun
, you pass something as a parameter -- without the declaration of fun
it's not possible to see whether this is a copy of a
, a reference to a
, or some other type constructed from a
.
In the case of the functor fun_t
, you copy a
once to construct the functor. You (nominally) pass a fun_t*
as this
to operator()
, and then a
is accessed as this->a
. The extra indirection might well be elided once everything is inlined and the optimizer has finished, but then again it might not. You would have to check specific cases, probably by examining the instructions emitted by the compiler.
Upvotes: 2
Reputation: 31445
There may be small optimisations you can make by changing the loop construct, but the main purpose of these is not for speed improvement.
If you want speed improvement you need to profile. If fun(a,k)
in particular is a slow operation and each run is not dependent on the others, you should consider splitting into threads and running each one on its own thread.
There are new APIs coming to operate over collections in parallel rather than series. Exciting times ahead.
Upvotes: 1
Reputation: 18358
I suppose the heavy computation is performed inside your function. Compared to that differences between direct function call and member function call should be insignificant.
Upvotes: 4