Hamza Nasab
Hamza Nasab

Reputation: 122

How to make iterating faster?

I have this loop:

for i in range(self.worldWidth):
    for j in range(self.worldHeight):
        originalValue = self.world.world[i, j]
        # Process newValue
        self.world.world[i, j] = newValue
        

When the world size is (500, 500), It runs around 10 times per second which is slow for what I'm doing, When I tried to do the same thing in C# I got triple the speed (30 times per second).
is there anyways to make it faster?

Note: These speeds are calculated without doing anything with the value

Edit: after further testing with C# I got around 10 times the speed (Just the first time was slow), But in python everytime its around 0.07sec

Upvotes: 0

Views: 88

Answers (2)

Tls Chris
Tls Chris

Reputation: 3934

Without knowing what you are trying to do but taking the numpy tag as an indicator. Numpy runs it's internal loops in compiled code so is much faster than using explicit Python loops.

import numpy as np

world = np.zeros( ( 500, 500 ) )

world[:] = 42

def test( world, v ):
    for r, row in enumerate( world ):
        for c, col in enumerate( row ):
            world[ r, c ] = v 

test( world, 42 )

%timeit world[:] = 42                                                   
# %timeit 110 µs ± 1.58 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit test( world, 43 )                                               
# 69.9 ms ± 1.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

If you need calculations these can also be much faster if they can be defined in numpy.

weight = np.arange( 500 )/250

def test_loop( world, weight ):
    w = world.copy()
    for r, row in enumerate( world ):
        for c, col in enumerate( row ):
            w[ r, c ] *= weight[c]
    return w

test_loop( world, weight )

def test_np( world, weight ):
    w = world.copy()
    return world * weight

np.isclose( test_loop( world, weight ),test_np( world, weight )).all()
# True  # The two results are equivalent.

%timeit test_np( world, weight )                                        
# 754 µs ± 1.71 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit test_loop( world, weight )                                      
# 172 ms ± 3.62 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

As some of the comments have hinted. It depends on what calculations you need to generate newValue. Given the potential improvements in calculation time it's probably worth exploring numpy for your application.

Upvotes: 1

IlayG01
IlayG01

Reputation: 108

maybe by declaring self.worldWidth and self.worldHeight as lists with the numbers inserted whiteout using the range keyword. that will save the calculation of the next() number each iteration.

NOTICE - this way will cause a memory waste compared to the range option that uses calculation of the next index in the loop.

Upvotes: 0

Related Questions