Language Shootout
David C. Ullrich
ullrich at math.okstate.edu
Wed Jul 11 10:48:13 EDT 2001
On Wed, 11 Jul 2001 01:47:30 GMT, bokr at accessone.com (Bengt Richter)
wrote:
>On Tue, 10 Jul 2001 13:54:47 GMT, ullrich at math.okstate.edu (David C.
>Ullrich) wrote:
>
>>On Tue, 10 Jul 2001 01:18:16 -0400, "Tim Peters" <tim.one at home.com>
>>wrote:
>>
>>>[Bengt Richter]
>>>> ...
>>>> I just did a python recursive fib(100000) in
>>>> just over 15 seconds, including startup and
>which turned out to be mostly str conversion for
>the print, so I thought I'd try recursion on that...
>(see below ;-)
Sorry I missed the "which turned out to be
mostly str conversion" the first time I read this.
>[...]
>>(Took a minute to find fib.py just now, because it was filed
>>under "MatrixTypes". I calculate fib(100000) in 1.7
>>seconds this way; for comparison, str(fib(100000)) takes
>>8.0 seconds.)
>Hi Dave ;-)
>
>Try strL for comparison. It's recursive, and faster than str
>for big numbers. I got
> >>> len(strL.strL(ffib(100000)))
> 20899
>
>so you can type in 10L**20899 on the command line
>for a number in the same ballpark as the fib, for a test.
>On my system I get
>
>[18:47] C:\pywk\fib>strL.py str 10L**20899
>str took 13.601617 seconds
>
>[18:47] C:\pywk\fib>strL.py strL 10L**20899
>strL took 1.044989 seconds
>
>Recursion rides again ;-)
Recursive or not, the idea that we can write
a replacement for str that's faster is very
curious.
>BTW, how do you put everything inside the strL def
>to hide names, and how do you recurse inside without
>a warning message?
>
>A couple of lines wrapped...
>_______________________________________________________________
># strL.py -- recursive long to decimal string conversion
># 2001-07-10 bokr
>#
>p10d={}
>def p10(n):
> if not p10d.has_key(n):
> p = p10d[n] = 10L**n
> return p
> return p10d[n]
>
>def strLR(n,w=0): # w>0 is known width, w<0 is searching guess
> if w == 0: return []
> if w > 0:
> if w <=9: return [('%0'+chr(w+48)+'d') % n]
> wr = w/2
> nl,nr = divmod(n,p10(wr))
> return strLR(nl,w-wr)+strLR(nr,wr)
> else:
> nl,nr = divmod(n,p10(-w))
> if nl:
> return strLR(nl, 2*w) + strLR(nr,-w)
> else:
> if w >= -9:
> return ['%d' % n]
> else:
> return strLR(nr,w/2)
>
>def strL(n):
> if n<0:
> return ''.join(['-']+strLR(-n,-9))
> else:
> return ''.join(strLR(n,-9))
Of course you have to do the recursion in a non-stupid
manner, as here; if you'd made a recurzive routine
that concatenated Python strings instead of building
that list I doubt that recursion would win. But it is
curious how often recursion does seem to win in Python.
(Doesn't usually beat built-in functions, though.)
>from time import clock
>import sys
>def main():
> def pr(x):
> print x
>
> def psl(x):
> s = strL(x)
> sys.stdout.write(s)
> sys.stdout.write('\n')
>
>
> dt={'str':str,'strL':strL,'repr':repr, 'print':pr, 'printStrL':psl
>}
>
> try:
> x=long( eval(sys.argv[2]) )
> fn=sys.argv[1]
> fcn=dt[fn]
> except:
> sys.stderr.write("usage: %s [str strL repr print printStrL]
><const expr>\n" % sys.argv[0])
> sys.exit(2)
>
> t0=clock()
> fcn(x)
> t1=clock()
> print "%s took %9.6f seconds" % (fn,t1-t0)
>
>if __name__ == "__main__":
> main()
>_______________________________________________________________
David C. Ullrich
More information about the Python-list
mailing list