Commit 857dddb4 authored by Stefan Behnel's avatar Stefan Behnel

add "meteor_contest" benchmark as demo of a program that Cython cannot speed...

add "meteor_contest" benchmark as demo of a program that Cython cannot speed up very much as the bulk of the work (set operations) is in CPython's own code
parent b3936524
cimport cython
cdef list rotate(list ido, dict rd=*)
cdef list flip(list ido, dict fd=*)
cdef list permute(list ido, list r_ido)
@cython.locals(n_i_min=long)
cpdef solve(long n, long i_min, free, list curr_board, list pieces_left, list solutions,
list fps=*, list se_nh=*, bisect=*)
# The Computer Language Benchmarks Game
# http://shootout.alioth.debian.org/
#
# contributed by Daniel Nanz, 2008-08-21
import optparse
import time
from bisect import bisect
import util
w, h = 5, 10
dir_no = 6
S, E = w * h, 2
SE = S + (E / 2)
SW = SE - E
W, NW, NE = -E, -SE, -SW
def rotate(ido, rd={E: NE, NE: NW, NW: W, W: SW, SW: SE, SE: E}):
return [rd[o] for o in ido]
def flip(ido, fd={E: E, NE: SE, NW: SW, W: W, SW: NW, SE: NE}):
return [fd[o] for o in ido]
def permute(ido, r_ido):
ps = [ido]
for r in xrange(dir_no - 1):
ps.append(rotate(ps[-1]))
if ido == r_ido: # C2-symmetry
ps = ps[0:dir_no//2]
for pp in ps[:]:
ps.append(flip(pp))
return ps
def convert(ido):
'''incremental direction offsets -> "coordinate offsets" '''
out = [0]
for o in ido:
out.append(out[-1] + o)
return list(set(out))
def get_footprints(board, cti, pieces):
fps = [[[] for p in xrange(len(pieces))] for ci in xrange(len(board))]
for c in board:
for pi, p in enumerate(pieces):
for pp in p:
fp = frozenset([cti[c + o] for o in pp if (c + o) in cti])
if len(fp) == 5:
fps[min(fp)][pi].append(fp)
return fps
def get_senh(board, cti):
'''-> south-east neighborhood'''
se_nh = []
nh = [E, SW, SE]
for c in board:
se_nh.append(frozenset([cti[c + o] for o in nh if (c + o) in cti]))
return se_nh
def get_puzzle(w=w, h=h):
board = [E*x + S*y + (y%2) for y in xrange(h) for x in xrange(w)]
cti = dict((board[i], i) for i in xrange(len(board)))
idos = [[E, E, E, SE], # incremental direction offsets
[SE, SW, W, SW],
[W, W, SW, SE],
[E, E, SW, SE],
[NW, W, NW, SE, SW],
[E, E, NE, W],
[NW, NE, NE, W],
[NE, SE, E, NE],
[SE, SE, E, SE],
[E, NW, NW, NW]]
perms = (permute(p, idos[3]) for p in idos) # restrict piece 4
pieces = [[convert(pp) for pp in p] for p in perms]
return (board, cti, pieces)
def print_board(board, w=w, h=h):
for y in xrange(h):
for x in xrange(w):
print(board[x + y * w])
print('')
if y % 2 == 0:
print('')
print()
board, cti, pieces = get_puzzle()
fps = get_footprints(board, cti, pieces)
se_nh = get_senh(board, cti)
def solve(n, i_min, free, curr_board, pieces_left, solutions,
fps=fps, se_nh=se_nh, bisect=bisect):
fp_i_cands = fps[i_min]
for p in pieces_left:
fp_cands = fp_i_cands[p]
for fp in fp_cands:
if fp <= free:
n_curr_board = curr_board[:]
for ci in fp:
n_curr_board[ci] = p
if len(pieces_left) > 1:
n_free = free - fp
n_i_min = min(n_free)
if len(n_free & se_nh[n_i_min]) > 0:
n_pieces_left = pieces_left[:]
n_pieces_left.remove(p)
solve(n, n_i_min, n_free, n_curr_board,
n_pieces_left, solutions)
else:
s = ''.join(map(str, n_curr_board))
solutions.insert(bisect(solutions, s), s)
rs = s[::-1]
solutions.insert(bisect(solutions, rs), rs)
if len(solutions) >= n:
return
if len(solutions) >= n:
return
return
SOLVE_ARG = 60
def main(n):
times = []
for i in xrange(n):
t0 = time.time()
free = frozenset(xrange(len(board)))
curr_board = [-1] * len(board)
pieces_left = list(range(len(pieces)))
solutions = []
solve(SOLVE_ARG, 0, free, curr_board, pieces_left, solutions)
#print len(solutions), 'solutions found\n'
#for i in (0, -1): print_board(solutions[i])
tk = time.time()
times.append(tk - t0)
return times
if __name__ == "__main__":
parser = optparse.OptionParser(
usage="%prog [options]",
description="Test the performance of the Float benchmark")
util.add_standard_options_to(parser)
options, args = parser.parse_args()
util.run_benchmark(options, options.num_runs, main)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment