一个数据对象而不是对象数组 - 为什么它更慢?

时间:2021-06-23 13:30:52

标签: python performance pygame conways-game-of-life

我目前正在编写一个带有小额外功能的生活游戏,但我遇到了一个问题 - 在我的第一次尝试中,我决定使用简单的 Cell 对象数组:

class Cell:
    def __init__(self, x, y, is_alive):
        self.is_alive = is_alive
        self.x = x
        self.y = y
        self.will_be_alive = False
        self.neighbours = 0

    def kill(self):
        self.will_be_alive = False

    def revive(self):
        self.will_be_alive = True

    def iterate(self):
        self.is_alive = self.will_be_alive

编辑: 这是 next_state 函数:

def next_state(cells):
    for row in cells:
        for cell in row:
            if cell.neighbours > 0:
                count_state(cells, cell)
            elif cell.neighbours == 0 and cell.is_alive:
                cell.kill()
    for row in cells:
        for cell in row:
            neigh_iterate(cells, cell)


def count_state(cells, cell):
    nei = neighboors(cells, cell)
    if (nei > 3 or nei < 2) and cell.is_alive:
        cell.kill()
    elif nei == 3 and not cell.is_alive:
        cell.revive()


def neigh_iterate(cells, cell):
    prev = cell.is_alive
    cell.iterate()
    if cell.is_alive != prev:
        if cell.is_alive:
            add_neighbour(cells, cell, 1)
        else:
            add_neighbour(cells, cell, -1)


def neighboors(cells, cell):
    how_many = -1 if cell.is_alive else 0
    for i in range(-1, 2):
        for j in range(-1, 2):
            if cells[(cell.y + i) % BOARD_HEIGHT][(cell.x + j) % BOARD_WIDTH].is_alive:
                how_many += 1
    return how_many

但现在我使用不同的方法:

class Cells:
    def __init__(self, width, height):
        self.current_states = [[False for i in range(width)] for j in range(height)]
        self.next_states = [[False for i in range(width)] for j in range(height)]
        self.neighbours = [[0 for i in range(width)] for j in range(height)]

如您所见,现在不是对象数组,而是带有数组的对象。 我希望我的程序运行得稍微快一点,但它完全相反 - 它少了 20 fps(从 62 到 41-42)。我认为,该问题可能出在第二种方式的迭代方法中:

def next_state(cells):
    for i, row in enumerate(cells.current_states):
        for j, cell in enumerate(row):
            if cells.neighbours[i][j] > 0:
                count_state(cells, j, i)
            elif cells.neighbours[i][j] == 0 and cells.current_states[i][j]:
                cells.next_states[i][j] = False
    for i, row in enumerate(cells.current_states):
        for j, cell in enumerate(row):
            neigh_iterate(cells, j, i)


def count_state(cells, x, y):
    nei = neighboors(cells.current_states, x, y)
    if (nei > 3 or nei < 2) and cells.current_states[y][x]:
        cells.next_states[y][x] = False
    elif nei == 3 and not cells.current_states[y][x]:
        cells.next_states[y][x] = True


def neigh_iterate(cells, x, y):
    prev = cells.current_states[y][x]
    iterate(cells, x, y)
    if cells.current_states[y][x] != prev:
        if cells.current_states[y][x]:
            add_neighbour(cells.neighbours, x, y, 1)
        else:
            add_neighbour(cells.neighbours, x, y, -1)


def neighboors(current_states, x, y):
    how_many = -1 if current_states[y][x] else 0
    for i in range(-1, 2):
        for j in range(-1, 2):
            if current_states[(y + i) % BOARD_HEIGHT][(x + j) % BOARD_WIDTH]:
                how_many += 1
    return how_many


def iterate(cells, x, y):
    cells.current_states[y][x] = cells.next_states[y][x]

你们有什么想法吗?

0 个答案:

没有答案
相关问题