-2

I was wondering what I could do to increase the overall speed of changing individual values in a NumPy array?

class Draw:
    def __init__(self, game, pygame):
        self.pygame = pygame
        self.game = game
        self.display = np.array([[random_color() for x in range(self.game.settings.PIX_ARRAY_HEIGHT)] for y in range(self.game.settings.PIX_ARRAY_WIDTH)])
    def draw_screen(self):
        self.pygame.surfarray.make_surface(self.display)
        surface = self.pygame.surfarray.make_surface(self.display)
        surface = self.pygame.transform.scale(surface, (self.game.settings.SCREEN_WIDTH, self.game.settings.SCREEN_HEIGHT))
        self.game.screen.blit(surface, (0, 0))
        self.pygame.display.update()

    def pixel(self, x, y, color, alpha=1):
        if x >= 0 and x < self.game.settings.PIX_ARRAY_WIDTH and y >= 0 and y < self.game.settings.PIX_ARRAY_HEIGHT:
            self.display[int(x), int(y)] = color if alpha == 1 else self.mix_pixels(color, self.display[int(x), int(y)], alpha)

    def rect(self, x, y, w, h, color):
        threads = []
        for i in range(x, x + w):
            for j in range(y, y + h):
                x = threading.Thread(target=self.pixel, args=(i,j,color,))
                threads.append(x)
                x.start()

I tried threading to increase the speed of overwriting pixels in the NumPy array but that seemed to decrease the overall speed.

I have tried to use numbas's njit and jit tool to pre-compile the code, but it refused to do so.

when a 100 x 100 rect is drawn the fps drops from 160+ to just over 3 without any threading with threading it goes to about 0.13 fps.

  • 2
    Please edit your question to include a [mcve], include error messages or tracebacks to problems you've encountered. – import random Jul 19 '22 at 22:58
  • See this [answer](https://stackoverflow.com/a/582337/2280890) for assistance on profiling python code. I think you want to use [`surfarray.pixels2d()`](https://www.pygame.org/docs/ref/surfarray.html#pygame.surfarray.pixels2d) to faster manipulation of pixel values. – import random Jul 20 '22 at 00:04
  • 1
    Your code is slow because the algorithm being used is slow. For starters it's re-scaling the image every time its drawn. Why not just rescale every time the image changes... or try not to rescale at all. – Kingsley Jul 20 '22 at 00:12
  • The Image is rescaled as there are fewer pixels to then be drawn, this is a pixel game after all, without any scaling it runs at 12fps which is a humungous drop in performance, rescaling the image is much faster. – Ico Twilight Jul 20 '22 at 13:09
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Jul 20 '22 at 13:12

1 Answers1

0

after changing the drawing technique I am using this code:

@njit(parallel=True, fastmath=True)
def blit(image1, image2, x, y):
    for i in prange(len(image2)):
        for j in prange(len(image2[0])):
            try:
                image1[int(i + x), int(j + y)] = image2[i, j]
            except:
                print(i, j)

the code is pre-compiled and runs on the GPU so is much much faster than it would be otherwise.

any suggestions to make it faster are highly sought after but I am happy with the results of over a constant 120 fps.