The Cost of Dynamism (was Re: Pyhon 2.x or 3.x, which is faster?)
Chris Angelico
rosuav at gmail.com
Sun Mar 13 17:44:15 EDT 2016
On Mon, Mar 14, 2016 at 8:26 AM, Christian Gollwitzer <auriocus at gmx.de> wrote:
> I assume you run this in a big loop. What about a single hash-table lookup?
>
> from collections import Counter
> counts=Counter()
> for c in whatever:
> counts[c]+=1
>
> upper=sum(counts[x] for x in range(ord('A'), ord('Z')+1)
> lower=sum(counts[x] for x in range(ord('a'), ord('z')+1)
> ....
>
>
> I think this is equally readable as the switch version, and should be much
> faster.
At this point, it's completely moved away from being a switch block,
so while it may well be more readable AND faster, it's pretty much
irrelevant to the discussion. The value of a switch block is arbitrary
code, same as an if/elif tree, without having to package stuff up into
functions. Although I could accept a function-based solution if it
looks clean enough...
case = switch(c)
@case("A", "Z")
def _():
do_uppercase_stuff
@case("a", "z")
def _():
do_lowercase_stuff
@case("0", "9")
def _():
do_digit_stuff
@case
def _():
do_default_stuff
It creates an inner scope, which most people won't need or want, and
it's creating a bunch of functions every iteration, but the code's
reasonably clean. And it's fairly implementable:
def switch(template):
def case(testme, *range):
if done is not case: return done # Already hit another case.
match = False
if isinstance(testme, type(case)):
# No parens - this is the default case
match = True
elif range:
match = testme <= template <= range[0]
else:
match = template == testme
if match:
done = testme()
return done
done = case # Sentinel: Not done yet.
return case
Now you can play around with performance questions. But not until the
code (a) does the right thing, and (b) looks good enough to maintain.
ChrisA
More information about the Python-list
mailing list