[Python-Dev] switch-based programming in Python

M.-A. Lemburg mal@lemburg.com
Thu, 08 Nov 2001 12:32:39 +0100


Thomas Wouters wrote:
> 
> On Wed, Nov 07, 2001 at 04:23:32PM +0100, M.-A. Lemburg wrote:
> 
> > Currently, dispatching of execution based on the value of
> > one variable is usually implemented by having some dictionary
> > of possible values and then calling method which implement the
> > different branches of execution. This works well for code which
> > uses medium sized methods, but fails badly for small ones such
> > as code which is often used in method callback based parsers.
> 
> Why does it not work well for small-sized methods ? 

The time needed for the call overhead is significant compared
to the execution time for the code of the small-sized method,
e.g. like in:

def handle_data(self, data):
    self.data.append(data)

> And how do you define
> 'well' ? 

'well' == fast :-)

> Would a lengthy if/elif/elif/else construct work better ?  Why ? 

Yes, because it doesn't involve calling methods, no execution
frames have to be setup, no arguments need to be passed in,
state can be managed in local variables, etc.

> And
> if not, what _would_ work better ? Or did you mean 'small numbers of
> methods' ?

No.
 
> > The alternative is using lengthy
> >       if x == 'one': ...
> >       elif x == 'two': ...
> >       elif x == 'three': ...
> >       else: ...default case...
> > constructs.
> 
> > Wouldn't it make sense to enable the byte code compiler to take
> > the above construct and turn it into a dictionary based
> > switch statement ?
> 
> Frankly, no, it wouldn't make sense. Not only do we not know the type of 'x'
> at compile time, but we also don't know how often 'x' changes type when you
> start comparing it with any kind of object. What _might_ work is something
> like:
> 
> x_key = str(x)
> if x == 'one': ...
> [etc]
> 
> But that would require a type inference mechanism first, and a
> is-str-being-masked-or-has-builtins-been-modified check. I think your best
> bet for adding those is in an external (python-written) bytecode-optimizer
> with complicated flow analysis.

Hmm, I'd rather not use a special compiler for this... ideal would
be a simple mechanism to pass the needed information ("please compile
this using a dictionary dispatch functionality") to the existing
compiler.
 
> If the problem with dict-based switches is the clumsiness of declaration,
> maybe something like this would improve matters:
> 
>    disp = dispatcher.dispatcher(
>         one=lambda x: ...
>         two=lambda x: ...
>         three=lambda x: ...
>         four=func_for_four
>         five=lambda: pass)
> 
>    disp.dispatch(x)

It would if the lambdas would be inlined by the compiler. Otherwise,
you'd have the same call overhead as for method callbacks.
 
> Or maybe you'd prefer using strings containing code fragments and exec'ing
> them. 

You'd have to compile the strings each time... exec'uting code
objects would be better, but then you again have to go through
the trouble of initializing locals etc.

> I'm not sure what you want the if/else to actually do. Personally, I
> either need a function call in there (in which case a dispatch table calling
> the function directly, sometimes with apply() or lambda-wrapper tricks, does
> fine) or some kind of variable assignment, in which case a simple dict
> lookup works just as fine. Then again, I don't write that much Python code.

You don't ?
 
> > I'm not talking about adding syntax to the language, it would
> > just be nice to have the compiler recognize this kind of code
> > (somehow; perhaps with some extra help) and produce optimized
> > code for it, possibly using new opcodes for the switching
> > operation.
> 
> I personally wouldn't be adverse to a switch-like syntax, as long as we
> define it like a dict dispatch (the argument is evaluated once, it should be
> hashable, and all the 'cases' should be hashable -- preferably even
> compile-time constants.) I like the idea, I'm just not sure if there's
> enough use for it.

That's the idea. 

There's enough need in it for my applications, so I'd go through 
the trouble of writing the code for it, provided I get the OK
and help from python-dev.

-- 
Marc-Andre Lemburg
CEO eGenix.com Software GmbH
______________________________________________________________________
Consulting & Company:                           http://www.egenix.com/
Python Software:                        http://www.lemburg.com/python/