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 range(n)]
31
marshal.dump(result, fp)
40
except IOError as msg:
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), end=' ')
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), end=' ')
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 range(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__':