home *** CD-ROM | disk | FTP | other *** search
- """Sort performance test.
-
- See main() for command line syntax.
- See tabulate() for output format.
-
- """
-
- import sys
- import time
- import whrandom
- import marshal
- import tempfile
- import operator
- import os
-
- td = tempfile.gettempdir()
-
- def randrange(n):
- """Return a random shuffle of range(n)."""
- fn = os.path.join(td, "rr%06d" % n)
- try:
- fp = open(fn, "rb")
- except IOError:
- result = []
- for i in range(n):
- result.append(whrandom.random())
- try:
- try:
- fp = open(fn, "wb")
- marshal.dump(result, fp)
- fp.close()
- fp = None
- finally:
- if fp:
- try:
- os.unlink(fn)
- except os.error:
- pass
- except IOError, msg:
- print "can't write", fn, ":", msg
- else:
- result = marshal.load(fp)
- fp.close()
- ##assert len(result) == n
- # Shuffle it a bit...
- for i in range(10):
- i = whrandom.randint(0, n-1)
- temp = result[:i]
- del result[:i]
- temp.reverse()
- result[len(result):] = temp
- del temp
- return result
-
- def fl():
- sys.stdout.flush()
-
- def doit(L):
- t0 = time.clock()
- L.sort()
- t1 = time.clock()
- print "%6.2f" % (t1-t0),
- fl()
-
- def tabulate(r):
- """Tabulate sort speed for lists of various sizes.
-
- The sizes are 2**i for i in r (the argument, a list).
-
- The output displays i, 2**i, and the time to sort arrays of 2**i
- floating point numbers with the following properties:
-
- *sort: random data
- \sort: descending data
- /sort: ascending data
- ~sort: many duplicates
- -sort: all equal
- !sort: worst case scenario
-
- """
- cases = ("*sort", "\\sort", "/sort", "~sort", "-sort", "!sort")
- fmt = ("%2s %6s" + " %6s"*len(cases))
- print fmt % (("i", "2**i") + cases)
- for i in r:
- n = 1<<i
- L = randrange(n)
- ##assert len(L) == n
- print "%2d %6d" % (i, n),
- fl()
- doit(L) # *sort
- L.reverse()
- doit(L) # \sort
- doit(L) # /sort
- if n > 4:
- del L[4:]
- L = L*(n/4)
- L = map(lambda x: --x, L)
- doit(L) # ~sort
- del L
- L = map(abs, [-0.5]*n)
- doit(L) # -sort
- L = range(n/2-1, -1, -1)
- L[len(L):] = range(n/2)
- doit(L) # !sort
- print
-
- def main():
- """Main program when invoked as a script.
-
- One argument: tabulate a single row.
- Two arguments: tabulate a range (inclusive).
- Extra arguments are used to seed the random generator.
-
- """
- import string
- # default range (inclusive)
- k1 = 15
- k2 = 19
- if sys.argv[1:]:
- # one argument: single point
- k1 = k2 = string.atoi(sys.argv[1])
- if sys.argv[2:]:
- # two arguments: specify range
- k2 = string.atoi(sys.argv[2])
- if sys.argv[3:]:
- # derive random seed from remaining arguments
- x, y, z = 0, 0, 0
- for a in sys.argv[3:]:
- h = hash(a)
- h, d = divmod(h, 256)
- h = h & 0xffffff
- x = (x^h^d) & 255
- h = h>>8
- y = (y^h^d) & 255
- h = h>>8
- z = (z^h^d) & 255
- whrandom.seed(x, y, z)
- r = range(k1, k2+1) # include the end point
- tabulate(r)
-
- if __name__ == '__main__':
- main()
-