increasing computational speed of a for loop

Viewed 55

I need to calculate some value for items in a list which represent nodes of a 3d network. The list shows the x,y, and z coordinates and values of the nodes. and I am trying the calculate the positional value of a node by summing up the nodes which are under the node in a downward cone. (like a pyramid for the calculated block)

  • rl_alternatives is max(z)
  • and the list consists of [3,4,2,55] like values

for item in network:

pw=0
for level in range(1,rl_alternatives):
    for i in range(len(network)):
        if network[i][2]==item[2]-level:
            if network[i][0]>=item[0]-level and network[i][0]<=item[0]+level:
                if network[i][1]<=item[1]+level and network[i][1]>=item[1]-level:
                    pw+=(network[i][3])         
item.append(pw)
                    

I am using this for loop and I tried cynthonizing it, multiprocessing it by pool() option. For loop is working itself but when the network is getting larger the computing time is increasing and becoming unreasonable. Cynthonizing is decreased its time by almost %10 but this is not enough. OTOH multiprocessing made it last longer.

Is there anyway that I can improve my loop in terms of computing time? I would be glad if anyone give me some ideas. Thanks in advance.

1 Answers

You could precalculate item[0]-level and item[0]+level further up the loops, since they will be constant for a certain level.

Improving only the readability as suggested:

pw = 0
for level in range(1, rl_alternatives):
    for node in network:
        if node[2] == item[2]-level:
            if node[0] >= item[0]-level and node[0]<=item[0]+level:
                if node[1]<=item[1]+level and node[1]>=item[1]-level:
                    pw+=node[3]

With precalculation this becomes:

pw = 0
for level in range(1, rl_alternatives):
    limit_low = item[0]-level
    limit_high = item[0]+level
    for node in network:
        if node[2] == item[2]-level:
            if node[0] >= limit_low and node[0] <= limit_high: # condition 1
                if node[1]<=item[1]+level and node[1]>=item[1]-level: # could be improved the same way
                    pw+=node[3]

I tried a simplified loop with timeit. Depending on the number of times you need to pass condition 1 it gave me boost of 5-15% (tested with passing the condition 7 - 11 times per loop). Hope that is useful for you.

Related