math.sqrt(x) versus x^0.5

I’ve set out on a quest for what some might argue is needless optimisation. One suggestion that I received on another forum post was to calculate some things inline, so I tried out substituting math.sqrt with ^0.5 and I couldn’t explain my results.

 

local mathSqrt = math.sqrt local getTimer = system.getTimer local t1, t2 = {}, {} local iterations = 100000 local number = 123456789 local start1 = getTimer() for i = 1, iterations do t1[i] = mathSqrt(123456789) -- t1[i] = mathSqrt(number) end local end1 = getTimer()-start1 local start2 = getTimer() for i = 1, iterations do t2[i] = 123456789^0.5 -- t2[i] = number^0.5 end local end2 = getTimer()-start2 print("mathSqrt: "..end1) print("^0.5: "..end2)

If I run the math.sqrt(x) function or x^0.5 calculation with a number, 123456789 in the example, then doing the straight up calculation is much faster. However, if I create a variable called number and set it to 123456789 and I then run math.sqrt(number) and number^0.5, then the function is clearly faster.

What’s going on here and is there something that I could do in order to capture the performance of doing the straight up calculation?

google “constant folding”

Alright, I now have a general understanding of how constant folding works, but I am still somewhat hazy regarding the specifics in this matter. Given the following code:

local number = 12345 local sqrt1 = number^0.5 local sqrt2 = 12345^0.5

Calculating sqrt2 is easily 2-3 times faster than sqrt1, but in terms of constant folding, since the value of the number is known as well, then shouldn’t it result in equally fast computation for both sqrt1 and sqrt2?

I found this post by Caleb P https://forums.coronalabs.com/topic/41034-optimization-calculate-roots-speed-plus-handy-root-function/. He made the same discovery that using x^0.5 is substantially faster than math.sqrt(x) in the event that x is actually inserted as a number, and not as a variable. If x is a variable, then math.sqrt(x) is substantially faster, which leads me to believe that it uses some other means of calculating the square root. 

 

you must have missed the key concept - one of your scenarios constant folding applies, one it does not…

sqrt1:  “number” is a variable, so constant folding does not (cannot) apply

at run time, the variable expression “number^0.5” is evaluated then assigned

sqrt2:  at compile time, the constant value “12345^0.5” is evaluated and replaced by ~111

at run time, all that executes is the constant assignment “sqrt2 = 111”

Alright. I must have just misunderstood that bit. Thanks for clearing it up. Seems like I will stick to using localised math.sqrt then.

google “constant folding”

Alright, I now have a general understanding of how constant folding works, but I am still somewhat hazy regarding the specifics in this matter. Given the following code:

local number = 12345 local sqrt1 = number^0.5 local sqrt2 = 12345^0.5

Calculating sqrt2 is easily 2-3 times faster than sqrt1, but in terms of constant folding, since the value of the number is known as well, then shouldn’t it result in equally fast computation for both sqrt1 and sqrt2?

I found this post by Caleb P https://forums.coronalabs.com/topic/41034-optimization-calculate-roots-speed-plus-handy-root-function/. He made the same discovery that using x^0.5 is substantially faster than math.sqrt(x) in the event that x is actually inserted as a number, and not as a variable. If x is a variable, then math.sqrt(x) is substantially faster, which leads me to believe that it uses some other means of calculating the square root. 

 

you must have missed the key concept - one of your scenarios constant folding applies, one it does not…

sqrt1:  “number” is a variable, so constant folding does not (cannot) apply

at run time, the variable expression “number^0.5” is evaluated then assigned

sqrt2:  at compile time, the constant value “12345^0.5” is evaluated and replaced by ~111

at run time, all that executes is the constant assignment “sqrt2 = 111”

Alright. I must have just misunderstood that bit. Thanks for clearing it up. Seems like I will stick to using localised math.sqrt then.