[Exceptional C++ Style] Exception C++ Style - Item 25: inline Redux.

Atul_Khot at i2.com Atul_Khot at i2.com
Fri Jan 28 01:11:45 EST 2005





The guideline is
      *** Inlining can happen anytime ****
so don't spend to much time in deciding which functions to inline. Resort
to inlining only when profilers
show the hotspot :-) s.
Inlining means replacing a function call with an "in-place" expansion of
the function's body.
Inlining are superficially similar to macros but without the evil
side-effects. An inline function
is still a function in every sense ( it might not get inlined at all and
just get called like a normal
i.e. non inlined function - see below ). You can take its address and don't
have to worry about
getting the arguments evaluated multiple times.

When we are talking about inlining, we are really talking about inlining
*** function calls ***.

Traditional aspects of inlining:

           Inlining is a request to the compiler. A compiler can rightly
ignore this request sometimes
and honour it other times. Why this is so? Because compilers typically have
more context to decide
whether inlining will really help or will slow down things. Better equipped
with this knowledge, compilers
will do the right thing. We programmers don't have this contextual
knowledge at coding time ( for example
I cannot know if some function, after applying optimizations would be too
large to fit into cache ). So we better
leave this tricky business to the compiler. Premature optimization is ( the
root of all :-) evil.
        Compilers can even inline functions that are not requested to be
inline.  The Square function in Example 25-1
is an example. [ My note: I reread that example and what stood out were the
two leading underscore in __temp.
Though this is pseudo code, I think this emphasizes another point -- A
compiler can use leading underscores
so *** we should not use it ***. ]

          Recursive functions can also be partly inlined. [ My note:
Compilers can replace tail recursion with a
goto statement ].

Somewhat modern aspects of inlining:

We might think that as a compiler compiles one module at a time, it cannot
perform inlining of a function which is in
some other module. This is true in the sense that the compiler won't
perform the inlining. However, inlining
can still be performed by the linker. And it can inline functions which
were written in Fortran or Pascal, provided the
appropriate protocols are observed ( parameter passing convention and stack
manipulation conventions ).

Modern aspects of inlining:

      C++/Java/.NET code can be compiled to byte code. This byte code is
the virtual machine instruction language
for an abstract computer. However, this byte code must be translated to
native machine code. This byte code to native code
translation is often done at application installation time. When this is
happening further optimizations/inlining can take place.
This byte code is language independent so a C# function can call and inline
a small C++ function.

Ultra modern aspects of inlining:

          Inlining can happen at runtime too. This, however, needs some
tool support. Two ways this can be done are
profile-directed optimizations and guarded inlining. [ My note:
http://www.artima.com/designtechniques/hotspot.html
describes a similar thing with Hotspot Virtual Machine ]
          In profile-directed optimizations, functions which are called
heavily are noted somehow and inlined. In other words,
the application is tuned at runtime. Compiers can routines nonvirtualize
and optionally inline virtual function calls if
they somehow can figure out the target type. [ My note: Dov Bulka and David
Mayhew gives an example of this
in "Efficient C++".  ]
      In Guarded Inlining, even if the target type cannot be determined
statically, the compilers still guess it and
non virtualize the call. However, this guess can be wrong and hence a run
time check is made. If the target
type is different a virtual call is made.

Finally, the JIT ( Just In Time ) compilation is mentioned. Here the
functions are compiled just before they
are going to be used. Instead of a big compilation, you end up doing lots
of little compilations. This might
slow down the initial program run. Other disadvantage is the optimizations
will suffer as the process can't spend
a lot of time in analyzing inlining and other optimization opportunities.
So if this analysis is done at install time,
we would be better off.

                  So the lesson is the later inlining is performed the
better it would be. And it is better done by
the tools than us.


- ciao,
  _
 /_|  _/         /
(   |  /   (_/  (

my i2 mail id scrawl .... :-)

printf "%d\n" 97 116 117  108 95 107 104 111 116 64 105 50 46 99 111 109 |
{ dd cbs=80 conv=block 2>/dev/null; echo; } | perl -pe 's/(\d+)/chr($1)/eg'




More information about the Effective-cpp mailing list