Each interface instance has the size of a struct containing two void pointers.[1] The same is true for the smart interface pointers manual_ptr and unique_ptr, and for the smart reference unique_obj. Instances of shared_ptr and shared_obj are slightly larger, because of the use of shared_count, but still of fixed size. This contrasts sharply with classes inheriting from abstract base classes, whose instances, in many C++ implementations, may contain several vtable pointers to handle multiple inheritance.
Invocation of a function through an interface instance involves a lookup in an array of function pointers and a call through a function pointer. The body of the function which is called indirectly conatins an invocation of the appropriate member function of the bound object. This second invocation is potentially inlinable.
Code using interfaces can be significantly faster than code using abstract classes, for the following reason. Within the body of a class member function which implements an interface member function, calls to other member functions of the same class may be eligible for inlining even if they also implement interface member functions. By contrast, within the implementation of a member function declared in an abstract class, calls to other functions declared in the base class use virtual function dispatch by default. The program hfront-test.cpp in the directory <libs/interfaces/test/hfront> illustrates that this can result in a significant performance difference when the indirect calls are made in an inner loop: in some cases code using interfaces executes nearly ten times as fast as similar code using virtual functions.[2] These result suggest that it may be feasible to use indirect calls through interface instances in some cases where the use of virtual functions would be prohibitively expensive.[3]
Boost.Interfaces uses preprocessor metaprogramming to construct C++ class definitions from IDL macros and template metaprogramming to construct interface function tables from these C++ class definitions. Both of these constructions require a significant amount of processing; as a result, compiling IDL interface definitions is significantly slower than compiling the defintions of abstract classes.
Boost.Interfaces makes heavy use of the The Boost Preprocessor Metaprogramming library (see [Karvonen]). Preliminary measurements involving the regression tests indicate that preprocessor metaprogramming represents a relatively small percentage of total compilation time. Preprocessing time can still make a significant difference with a large project, however, especially with a slow preprocessor such as EDG.
The construction of an interface function table is an iterative process with length roughly equal to the total number of functions in the interface, including inherited functions, plus the total size of the inheritance graph. It is therefore an O(N) construction a with a relatively small N in most cases. Nonetheless, since each step requires a significant number of template instantiations, the overall cost can be high.
A certain amount of additional compiation time may be acceptable if there are gains in other areas. It remains to be seen what effect the additional compilation time will have on real-world projects. In any case, there are several ways that compilation times might be improved:
<boost/interfaces/detail/invoker.hpp> and <boost/interfaces/detail/function_traits.hpp>.
[1]See Implementation, note 1.
[2]This program originally appeared in the C/C++ Users Journal, together with sample output showing execution times. See [Diggins2]
[3]In some cases the performance penalty associated with virtual functions can be negated by explicitly qualifying the intra-object calls to disable virtual function dispatch. However, when a class hierarchy has been designed around the use of virtual functions, disabling virtual function dispatch may yield the wrong semantics. Furthermore, disabling virtual function dispatch is often impossible: the desired functionality may be accessible only through a public non-virtual member function which invokes a private virtual function.
[4]See [Abrahams].
Revised 13 Jan, 2005
© Copyright Jonathan Turkanis, 2005. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Sha'arei Tefila, an Orthodox Shul (Synagogue) in Salt Lake City, Utah Chabad Lubavitch of Utah