Reputation: 1029
I have a statement computing a multiply-accumulate operation that looks something like this:
return A->set(A->get() + B->get() * C->get());
Now, A, B, and C may not be unique, and I want to minimize redundant get()
s. The only way I can think of optimizing this is with
if (A == B && B == C) {
double a = A->get();
return A->set(a + a * a);
} else if (A == B) {
double a = A->get();
return A->set(a + a * C->get());
} else if (A == C) {
double a = A->get();
return A->set(a + B->get() * a);
} else if (B == C) {
double b = B->get();
return A->set(A->get() + b * b);
} else {
return A->set(A->get() + B->get() * C->get());
}
Is there a more efficient way? What about generalizing this to more than three arguments??
Upvotes: 1
Views: 51
Reputation: 10665
You can store them in a map. The solution can be extended easily to arbitrarily many pointers, but I've used three here for concreteness.
std::unordered_map<MyType *, double> computed_values;
for (MyType *p: {A, B, C}) {
if (computed_values.find(p) == computed_values.end()) {
computed_values[p] = p->get();
}
}
double result = computed_values[A] + computed_values[B] * computed_values[C];
A->set(result);
As others have pointed out, make sure you profile to make sure this is actually worth the overhead of std::unordered_map
lookups.
Upvotes: 2
Reputation: 7542
Assuming get()
methods are really costly to the extent of producing measurable performance difference,
double a,b,c;
a = A->get();
b = (B==A?a:B->get());
c = (C==B?b:(C==A?a:c->get()));
return A->set(a+b*c);
Upvotes: 1
Reputation: 9682
Assuming the get() methods are reasonably cheap, you'd be better off just doing:
return A->set(A->get() + B->get() * C->get());
The other approach simply inserts a bunch of conditional jumps into your code, which could easily end up being more expensive than the original code.
Upvotes: 0