1 """Sort performance test.
3 See main() for command line syntax.
4 See tabulate() for output format.
15 td
= tempfile
.gettempdir()
18 """Return a list of n random floats in [0, 1)."""
19 # Generating floats is expensive, so this writes them out to a file in
20 # a temp directory. If the file already exists, it just reads them
21 # back in and shuffles them a bit.
22 fn
= os
.path
.join(td
, "rr%06d" % n
)
27 result
= [r() for i
in xrange(n
)]
31 marshal
.dump(result
, fp
)
41 print "can't write", fn
, ":", msg
43 result
= marshal
.load(fp
)
47 i
= random
.randrange(n
)
53 assert len(result
) == n
63 print "%6.2f" % (t1
-t0
),
67 """Tabulate sort speed for lists of various sizes.
69 The sizes are 2**i for i in r (the argument, a list).
71 The output displays i, 2**i, and the time to sort arrays of 2**i
72 floating point numbers with the following properties:
75 \sort: descending data
77 3sort: ascending, then 3 random exchanges
78 +sort: ascending, then 10 random at the end
79 %sort: ascending, then randomly replace 1% of the elements w/ random values
80 ~sort: many duplicates
82 !sort: worst case scenario
85 cases
= tuple([ch
+ "sort" for ch
in r
"*\/3+%~=!"])
86 fmt
= ("%2s %7s" + " %6s"*len(cases
))
87 print fmt
% (("i", "2**i") + cases
)
91 print "%2d %7d" % (i
, n
),
98 # Do 3 random exchanges.
99 for dummy
in range(3):
100 i1
= random
.randrange(n
)
101 i2
= random
.randrange(n
)
102 L
[i1
], L
[i2
] = L
[i2
], L
[i1
]
105 # Replace the last 10 with random floats.
107 L
[-10:] = [random
.random() for dummy
in range(10)]
110 # Replace 1% of the elements at random.
111 for dummy
in xrange(n
// 100):
112 L
[random
.randrange(n
)] = random
.random()
115 # Arrange for lots of duplicates.
119 # Force the elements to be distinct objects, else timings can be
121 L
= map(lambda x
: --x
, L
)
125 # All equal. Again, force the elements to be distinct objects.
126 L
= map(abs, [-0.5] * n
)
130 # This one looks like [3, 2, 1, 0, 0, 1, 2, 3]. It was a bad case
131 # for an older implementation of quicksort, which used the median
132 # of the first, last and middle elements as the pivot.
134 L
= range(half
- 1, -1, -1)
135 L
.extend(range(half
))
136 # Force to float, so that the timings are comparable. This is
137 # significantly faster if we leave tham as ints.
143 """Main program when invoked as a script.
145 One argument: tabulate a single row.
146 Two arguments: tabulate a range (inclusive).
147 Extra arguments are used to seed the random generator.
150 # default range (inclusive)
154 # one argument: single point
155 k1
= k2
= int(sys
.argv
[1])
157 # two arguments: specify range
158 k2
= int(sys
.argv
[2])
160 # derive random seed from remaining arguments
162 for a
in sys
.argv
[3:]:
163 x
= 69069 * x
+ hash(a
)
165 r
= range(k1
, k2
+1) # include the end point
168 if __name__
== '__main__':