inline function call

Bengt Richter bokr at oz.net
Thu Jan 5 19:58:59 CET 2006


On Thu, 05 Jan 2006 08:47:37 +1100, Steven D'Aprano <steve at REMOVETHIScyber.com.au> wrote:

>On Wed, 04 Jan 2006 13:18:32 +0100, Riko Wichmann wrote:
>
>> hi everyone,
>> 
>> I'm googeling since some time, but can't find an answer - maybe because 
>> the answer is 'No!'.
>> 
>> Can I call a function in python inline, so that the python byte compiler 
>> does actually call the function, but sort of inserts it where the inline 
>> call is made? Therefore avoiding the function all overhead.
>
>The closest thing to that is the following:
>
>
># original version:
>
>for i in xrange(100000):
>    myObject.something.foo()  # three name space lookups every loop
>
>
># inline version:
>
># original version:
>
>foo = myObject.something.foo
>for i in xrange(100000):
>    foo()  # one name space lookup every loop
>
But that isn't in-lining, that's hoisting some expression-evaluation
out of a loop on the assumption that the expression has constant value
and no side effects. That's good optimization, but it isn't in-lining.
Inlining is putting code to accomplish what foo does in place of the foo call.
E.g. if under simple conditions and assumptions you in-lined

    def foo(x,y):return 2*x+y+1
in
    a = 3*foo(b,c)

the code would be

    a = 3*(2*b+c+1)

This could be achieved by a custom import function that would capture the AST
and e.g. recognize a declaration like __inline__ = foo, bar followed by defs
of foo and bar, and extracting that from the AST and modifying the rest of the
AST wherever foo and bar calls occur, and generating suitable substitutions of
suitable AST subtrees generated from the ASTs of the foo and bar ASTs and rules
for renaming and guaranteeing safe temporary names etc. The modified AST would
then pass through the rest of the process to compilation and execution for the
creation of a module. You just wouldn't be able to plain old import to do the
importing (unless you had the custom import hooked in, and assumed that sources
without __inline__ = ... statements would not occur unintended.

Without hooking, usage might look like

    import inliner
    mymod = inliner.__import__('mymod') # side effect to mymod.pyc and sys.modules

and then you could expect calls to designated and defined inline functions in mymod.py
to have been inlined in the code of mymod.

I've been meaning to do a proof of concept, but I've hinted at these things before,
and no one seems much interested. And besides it's really a distraction from more radical
stuff I'd like to try ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list