0

I have been trying to make 3D drawing library for python 3, using Pygame. I want to use Z-Buffer so I need to call function for each pixel that should be drawn. Problem is that drawing 100x100 pixel rectangle takes more than 1 millisecond. Drawing function for rectangle is nested loop with function call and it can be simplified to this code to show the biggest bottleneck:

def another_function():
    pass

def test_function():
    for j in range(100):
        for k in range(100):
            another_function()

Function another_function() which does nothing is called 10000 times total. When I measured execution time, timeit has shown that test_function() takes 1.09 millisecond. This is too long because it is necessary to draw multiple rectangles and to achieve 60 frames per second, one frame must take less than 17 milliseconds.

I tried searching for solutions but I have been unable to find any way to increase speed of nested for loops with function calls besides using PyPy and Cython.

Additional information: I am using Python 3.5.2 with Windows 10 64-bit as OS. I didn't find any installer for PyPy for Windows and Cython has problem when compiling modules converted to .c so I can't use it.

  • do your function inline? – jeremycg Jul 19 '17 at 20:42
  • The PyPy for windows can be found here: https://bitbucket.org/pypy/pypy/downloads/ – tupui Jul 19 '17 at 21:11
  • 1
    _When your Python has performance trouble / your loops and calls run too slowly / remember the old wisdom: / **write in C**!_ – zwer Jul 19 '17 at 21:15
  • The loops aren't what's killing you. The function call is. An easy way to tell that is comment out the function call and then time it. – Mike Dunlavey Jul 19 '17 at 21:33
  • @zwer Using C isn't solution because I have issue with compiler (I think that more exactly with linker). This issue is preventing me from using Cython. –  Jul 20 '17 at 15:11
  • @Alven - trust me, fixing your C environment is a far, **far** easier task than forcing Python to do something it was never designed for. – zwer Jul 20 '17 at 15:15

1 Answers1

2

It would depend on what you are actually doing into another_function(). If you can use some numpy broadcasting, you can achieve some C speed. Indeed, even with the latest improvements in python 3.6, for loops are still to avoid for performance reasons.

See this answer for example. There is a 900X performance boost over a loop when numpy is properly used.

Also, you did not mentioned it but you can go with numba and its just in time compiler. This is particularly well suited in case of pure python loops.

tupui
  • 5,738
  • 3
  • 31
  • 52