please help me.
I wrote a program to run "Game of Life" with PyQt6 but, it runs very very slow. How can I make it faster?
- What about using multiple cores of the CPU? How can a Python program run on multiple cores?
- What about doing display stuff with GPU? How can a Python program work with the GPU?
- What about writing the code itself faster? I know Python is not a fast language but, what can I do to improve the speed of code as much as possible?
main.py
from numpy import empty
from sys import argv
from cell import cell
from PyQt6.QtCore import Qt, QTimer
from PyQt6.QtGui import QBrush, QColor, QKeyEvent, QPainter, QPen, QPaintEvent
from PyQt6.QtWidgets import QApplication, QWidget
class Window(QWidget):
def __init__(self, parent = None) -> None:
super().__init__(parent)
self.windowWidth = 1000
self.windowHeight = 1000
self.resolution = 2
self.cells = empty((self.windowWidth // self.resolution, self.windowHeight // self.resolution), dtype=object)
cellsShape = self.cells.shape
for i in range(cellsShape[0]):
for j in range(cellsShape[1]):
self.cells[i][j] = cell(i, j, self.resolution)
self.setWindowTitle("Game of Life")
self.setGeometry((1920 - 800) // 2, (1080 - 800) // 2, 800, 800)
self.setStyleSheet("background-color:rgb(20, 20, 20);")
self.graphicTimer = QTimer(self)
self.baseTimer = QTimer(self)
self.graphicTimer.timeout.connect(self.update)
self.graphicTimer.start(30)
self.show()
def run(self) -> None:
for rows in self.cells:
for cell in rows:
cell.calculateNewState(self.cells)
for rows in self.cells:
for cell in rows:
cell.setNewState()
def keyPressEvent(self, event: QKeyEvent) -> None:
key = event.key()
if key == Qt.Key.Key_S:
self.closeWindow()
event.accept()
def paintEvent(self, event: QPaintEvent) -> None:
self.run()
painter = QPainter()
painter.begin(self)
painter.setPen(QPen(QColor(20, 20, 20), -1, Qt.PenStyle.SolidLine))
painter.setBrush(QBrush(QColor(255, 255, 255), Qt.BrushStyle.SolidPattern))
for rows in self.cells:
for cell in rows:
if cell.state == True:
painter.drawRect(cell.posX * cell.cellWidth, cell.posY * cell.cellWidth, cell.cellWidth, cell.cellWidth)
painter.end()
event.accept()
def closeWindow(self) -> None:
print("closing window ...")
self.close()
if __name__ == "__main__":
App = QApplication(argv)
window = Window()
exit(App.exec())
cell.py
from numpy.random import choice
from PyQt6.QtWidgets import QWidget
class cell(QWidget):
def __init__(self, x, y, width, state = None, parent = None) -> None:
super().__init__(parent)
self.posX = x
self.posY = y
self.cellWidth = width
self.state = state
if self.state == None:
self.state = choice([True, False])
self.newState = None
self.aliveNeighbors = 0
def countAliveNeighbors(self, cells) -> None:
cellsShape = cells.shape
self.aliveNeighbors = 0
for i in range(-1, 2):
for j in range(-1, 2):
neighbor = cells[(self.posX + i + cellsShape[0]) % cellsShape[0]][(self.posY + j + cellsShape[1]) % cellsShape[1]]
if neighbor.state == True:
self.aliveNeighbors += 1
if self.state == True:
self.aliveNeighbors -= 1
def calculateNewState(self, cells) -> None:
self.countAliveNeighbors(cells)
if self.state == False and self.aliveNeighbors == 3:
self.newState = True
elif self.state == True and (self.aliveNeighbors > 3 or self.aliveNeighbors < 2):
self.newState = False
else:
self.newState = self.state
def setNewState(self) -> None:
self.state = self.newState
self.newState = None
I want to write code that runs as fast as possible