Dusan
Dusan

Reputation: 95

C++ Advantage of Proxy Classes

Scott Meyers says in "Effective Modern C++" that the expression

Matrix sum = m1 + m2 + m3 + m4

(where all objects have type Matrix) "can be computed much more efficiently if operator+ for Matrix objects returns a proxy for the result instead of the result itself. That is, operator+ for two Matrix objects would return an object of a proxy class such as Sum<Matrix, Matrix> instead of a Matrix object. This would encode the entire initialization expression, i.e., be something like Sum<Sum<Sum<Matrix, Matrix>, Matrix>, Matrix>.".

Now, I understand that proxy classes emulate behaviour of some other classes and do implicit converisons, but how and why is proxy approach in this case more efficient?

Best regards

Upvotes: 0

Views: 638

Answers (2)

xeonqq
xeonqq

Reputation: 63

To demonstrate how it works in code, I have implemented an example here invisible proxy which mimics the description from the book.

As written in the example, lazy evaluation happens at the copy Ctor of Matrix (Line 30), where calculation is actually performed. It is more efficient, because no temporary object is created, rather calculated directly in place.

I also did a performance comparison using callgrind between traditional OO based implementation and the template expression based implementation.

Setup:

  • Matrix Size: (1, 2000)
  • Expression to be evaluated: mat_a + mat_a + mat_a + mat_b + mat_c;

Result:

template expression (cost: 618037)

vs

object oriented + operator (cost: 944424)

Upvotes: 0

Sebastian Redl
Sebastian Redl

Reputation: 71899

Consider that Matrix might be an arbitrary-sized matrix, so it has to allocate storage for its elements from the heap. Adding two matrices together means allocating storage and doing the element-wise copy.

In the expression above, that means allocating storage once for (m1 + m2), for adding the result of that to m3, and a third time for adding that to m4. (Move semantics can reduce this cost.)

If the addition instead returns a proxy that just represents the addition while holding references to the things being added together, you only allocate once, for the final assignment.

With more work behind the scenes, it's possible to be even more lazy and calculate only those elements of the result matrix that are needed, on-demand.

However, these things are always a trade-off and you need to evaluate the costs and benefits in each case.

Upvotes: 2

Related Questions