# [SOLVED] Why is one function of divisor >3000% faster than the other?

## Issue

I was doing some simple Python exercises on https://www.practicepython.org/ when I did this task https://www.practicepython.org/exercise/2014/02/26/04-divisors.html.

I wanted to test different ways to code the answer, and I saw solutions in the comment field that piqued my interest; two codes looked similar, but one is almost 4000% faster than the other!

Code:

``````import time

start = time.time()

print("Fast code:")

#the slow code
def divisor(x):
divisors = []
for i in range(1, int(x)):
if x % i == 0:
divisors.append(i)
divisors.sort()
print(divisors)

divisor(50000000)
end = time.time()
print("Time elapsed: ")
print(end - start)

print("Fast code:")

start = time.time()

#the fast code!
def divisor2(x):
divisors = []
for i in range(1, int(x**.5)):
if x % i == 0:
divisors.append(i)
divisors.append(x//i)
divisors.sort()
print(divisors)
divisor2(50000000)
end = time.time()
print("Time elapsed: ")
print(end - start)
``````

Time elapsed (slow code):

``````3.1739981174468994
``````

Time elapsed (fast code):

``````0.0010004043579101562
``````

Can anyone please tell me how this is possible so perhaps anyone can take home some valuable faster coding skills for their toolbelt?

## Solution

`x**.5` is x to the power of a half, it’s a square root.

Both using `x = 50,000,000`, the first does:

``````for i in range(1, int(x)):
``````

fifty million loops.

The second does:

``````for i in range(1, int(x**.5)):
``````

seven thousand loops.

The reason you can do this when calculating divisors is because they form two sides of a rectangle:

`````` __
|  |
|  |
|__|
``````

If you know the area (the goal, 50 million), and you know one side (the counter `i`) then you can work out the other side. Where both sides are the same is the square root, and it acts like a pivot, if one is shorter than that then the other must be longer, and balance it out. That is, `100/2 = 50` that gives you both 2 and 50.

So you can count up to the square root to find all the short answers, work out the other side (the counter-balance) for each one, and then you have all the answers. `100/10 = 10` that gives you 10 as a divisor, and tells you that if you keep counting up to get to `100/50 = 2` you’ve already seen that from the other side and got 50.

That’s why the second code has:

``````        divisors.append(i)
divisors.append(x//i)
``````

Adding two values to the list, after only testing one.