Search code examples
pythonalgorithmtiming

Python nested-loop speed comparison unexpectedly slower when computing intermediate expression


In the case where python executes more operations, it is slower.

The following is a very simple comparison of two separate nested loops (for finding a Pythagorean triple (a,b,c) which sum to 1000):

#Takes 9 Seconds
for a in range(1, 1000):
  for b in range(a, 1000):
    ab = 1000 - (a + b)
    for c in range(ab, 1000):
      if(((a + b + c) == 1000) and ((a**2) + (b**2) == (c**2))):
        print(a,b,c)
        exit()


#Solution B
#Takes 7 Seconds
for a in range(1, 1000):
  for b in range(a, 1000):
    for c in range(b, 1000):
      if(((a + b + c) == 1000) and ((a**2) + (b**2) == (c**2))):
        print(a,b,c)
        exit()

I expected solution A to shave a second or two off of solution B but instead it increased the time it took to complete. by two seconds.

instead of iterating
1, 1, 1
1, 1, 2
...
1, 1, 999
1, 2, 2

It would iterate
1, 1, 998
1, 1, 999
1, 2, 997
1, 2, 998
1, 2, 999
1, 3, 996

It seems to me that solution a should vastly improve speed by cutting out thousands to millions of operations, but it in fact does not.

I am aware that there is a simple way to vastly improve this algorithm but I am trying to understand why python would run slower in the case that would seem to be faster.


Solution

  • You can just count total amount of iterations in each solution and see that A takes more iterations to find the result:

    #Takes 9 Seconds
    def A():
     count = 0
     for a in range(1, 1000):
      for b in range(a, 1000):
        ab = 1000 - (a + b)
        for c in range(ab, 1000):
          count += 1
          if(((a + b + c) == 1000) and ((a**2) + (b**2) == (c**2))):
            print(a,b,c)
            print('A:', count)
            return
    
    
    #Solution B
    #Takes 7 Seconds
    def B():
     count = 0
     for a in range(1, 1000):
      for b in range(a, 1000):
        for c in range(b, 1000):
          count += 1
          if(((a + b + c) == 1000) and ((a**2) + (b**2) == (c**2))):
            print(a,b,c)
            print('B:', count)
            return
    
    A()
    B()
    

    Output:

    A: 115425626
    B: 81137726
    

    That's why A is slower. Also ab = 1000 - (a + b) takes time.