[Tutor] script too slow

Paul Tremblay phthenry@earthlink.net
Sat Mar 1 11:09:02 2003


On Sat, Mar 01, 2003 at 12:56:15PM +0300, antonmuhin at rambler.ru wrote:
> 
> Disclaimer: everywhere I write 'faster' or 'slower' I mean that it is
> faster in my environment (ActiveState Python2.2 on WinXP) and in my
> toy examples :)
> 

Yes, absolutely!

> Saturday, March 1, 2003, 12:11:37 PM, you wrote:
> 
> PT> *********************************************************
> 
> 
> PT> # rewritten script uses dictionaries as 'case' statements
> PT> # This replaces the multiple if elif statements
> PT> # The resulting code is amazing simple and clean
> 
> PT> def initiate_dict(self):
> PT>         self.dict_token = 
> PT>         {
> 
> PT>         '*'                     :   ('*', self.default_func),
> PT>         ':'                     :   (':', self.default_func),
> PT>         '{'                     :   ('{', self.ob_func),
> PT>         '}'                     :   ('}', self.cb_func),
> PT>         # ect hundreds of lines of dictionary entries
> PT>         }
> Sorry for repeating, but still: playing around with your previous
> snippet I tried to use dictionaries instead of if-elif-else (I do
> really like dictionaries for this kind of things). Surprisingly it was
> slower! Therefore, I'd sugegst you to clock both variants and to
> find out which one is fatser.
> 

Hmm. Overall, my the second part of my module ran about 3 times faster
when I used dictionaries rather than elif. However, I changed several
things at once, so I guess I would have to change just one part of my
code and test it.

> PT> def process_cw(self, token):
> PT>         # some minor preliminary stuff for small exceptions
> 
> PT>         token, action = self.dict_token.get(token, (None, None))
> 
> 
> PT>         if action:   
> PT>             to_print = action(token, num) 
> PT>             return to_print
> Two last lines can be written as
> 
>                 return action(token, num)
> 
> And it might be faster.
> 
> Maybe this function can be boosted a little bit more:
> 
> def process_cw(self, token):
>      # some minor preliminary stuff for small exceptions
> 
>     action = self.dict_token.get(token)
>     if action:
>        return action[1](action[0], num)
> 
> At least ActiveState Python 2.2 on WinXP favors idiom:
>     el = d.get(key)
>     if el:
>        # do something with el[1]
> 
> over
> 
>     _, x = d.get(key, (None, None))
>     if x:
>        # do something with x
> 
> It might be because of tuple pack/unpack
> 
> And the last note: self.dict_token.get should take some valuable time.
> You might be better with passing self.dict_token.get in all the
> functions as a parameter

This suggestion confuses me. So far as I can tell, I'm using the lookup
only in one function, when I have to. Each token gets only one lookup if
it starts with a "\\". Can you give me an example?

> 
> PT> def process_tokens(self):
> PT>         # open file and read one token at a time...
> PT>         ...
> PT>             if token[0:1] == "\\":
> PT>                 line = self.process_cw(token)
> PT>                 if line != None:
> PT>                     write_obj.write(line)
> token[0] seems to be a little bit faster.
> 
> PT>             else:
> PT>                 line = 'tx<nu<nu<nu<nu<%s\n' % token
> PT>                 write_obj.write(line)
> 'tx<nu<nu<nu<nu<' + tokeb + '\n' seems to be a little bit faster. And
> you may factor out appending '\n' to all the lines in caller that
> might save some more time too, especially if you'll use something like
> join or print.
> 
> PT>                 # can I do:
> PT>                 # write_obj.write('tx<nu<nu<nu<nu%s\n' % token) ?
> PT>                 # probably--will have to try
> You should be able and I suppose it to be faster too.

I'll try these suggestions.

Thanks!

Paul

-- 

************************
*Paul Tremblay         *
*phthenry@earthlink.net*
************************