[pypy-issue] Issue #2357: pypy code ~50x slower than python (pypy/pypy)

oscardssmith issues-reply at bitbucket.org
Sun Jul 31 15:29:45 EDT 2016


New issue 2357: pypy code ~50x slower than python
https://bitbucket.org/pypy/pypy/issues/2357/pypy-code-50x-slower-than-python

oscardssmith:

I was making a sudoku solver using numpy (code below). When I run it on python2, it takes 160ms. On PyPy, it is 7.8s. Any ideas why it is so much slower using pypy?

from time import time
from itertools import product
import numpy as np

class board:
    def __init__(self, state):
        self.board = np.asarray(state,np.int)
        self.size = len(state)
        self.vals = set(range(self.size+1))

    def square_vals(self, coord):
        x, y = coord[0]//3*3, coord[1]//3*3
        return self.board[x:x+3, y:y+3]

    def empty(self):
        return list(map(tuple, np.transpose(np.nonzero((self.board == 0)))))

    def valid_move(self, coord, value):
        return value not in self.board[coord[0]] and value not in self.board[:, coord[1]] and value not in self.square_vals(coord)

    def valid_moves(self, coord):
        return self.vals.difference(np.concatenate((self.board[coord[0]], self.board[:, coord[1]],  self.square_vals(coord).flatten())))

    def valid_board(self):
        for row, col in product(range(self.size), range(self.size)):
            value = self.board[(row, col)]
            self.board[(row, col)] = 0
            if not (value not in self.board[row]] and value not in self.board[:, col] and value not in self.square_vals((row,col)):
                return False
            self.board[(row, col)] = value

        return True
    def __repr__(self):
        return "".join(''.join(str(row)[1:-1]) + '\n' for row in self.board)

def solve(board):
    change_num = 0
    empty, possible = board.empty(), dict()
    while i < len(empty):
        possible[empty[i]] = board.valid_moves(empty[i])

        if len(possible[empty[i]]):
            board.board[empty[i]] = min(possible[empty[i]])
            change_num += 1
        else:
            while len(possible[empty[i - 1]]) == 1:
                i -= 1
                board.board[empty[i]] = 0
            i -= 1
            change_num += 1
            possible[empty[i]].remove(min(possible[empty[i]]))
            board.board[empty[i]] = min(possible[empty[i]])
        i+=1
    print(board)
    print(change_num)

t1 = time()
trial = board([
        [3, 0, 0, 0, 0, 7, 0, 0, 9],
        [0, 0, 8, 0, 0, 0, 5, 0, 7],
        [2, 7, 4, 0, 8, 0, 0, 0, 0],
        [0, 0, 0, 0, 2, 0, 0, 0, 4],
        [0, 0, 7, 4, 0, 3, 1, 0, 0],
        [5, 0, 0, 0, 7, 0, 0, 0, 0],
        [0, 0, 0, 0, 6, 0, 4, 9, 8],
        [4, 0, 9, 0, 0, 0, 3, 0, 0],
        [1, 0, 0, 8, 0, 0, 0, 0, 0],
        ])
print(trial)
solve(trial)
print(1000*(time() - t1))
print(trial.valid_board())







More information about the pypy-issue mailing list