Search code examples
javascriptperformance-testing

Why does sqrt calculation take longer than pythagoras?


I recently tried to benchmark the performance of several JavaScript engines to check the performance of a sorting algorithm I wrote. In the process I stumbled across a behaviour I can't explain. In V8 and Spidermonkey the pythagoras function is calculated mostly within the same time as sqrt sometimes EVEN FASTER! Since sqrt is part of the calculation I would assume it should be much slower over 10000000 iterations ... It seems only in Chakra pythagoras is consitently calculated about 3-4 seconds slower.

computer:

  • OS : Win 10 64 Bit
  • CPU : i5-8250U 4 core
  • RAM : 8 GB

with latest available versions of each browser at this time (Chrome, Firefox and Edge)

Here is my benchmark script:

var out = document.getElementById("output")

var start, temp,
    lat1 = 14, lat2 = 28, lon1 = 12, lon2 = 24,
    steps = 10000000

start = Date.now()

for(var i = 0; i < steps; i++) {
    temp = Math.sqrt(lat2)
}

out.innerHTML += '<div> sqrt : ' + (Date.now() - start) + '</div>'

// pythagoras

start = Date.now();

for(var i = 0; i < steps; i++) {
    temp = Math.sqrt(Math.pow(lat2 - lat1, 2) + Math.pow(lon2 - lon1, 2))
}

out.innerHTML += '<div> pythagoras : ' + (Date.now() - start) + '</div>'

PS: the setRandomLatLon() almsot consistentently takes around 122 ms (in V8 at least)


Solution

  • Thanks for the suggested solutions. The test case now seems to work properly (considering it produces the expected results).

    The main change now was to vary the used lat, lon values with each iteration using a function that almost always executes over the same amount of time.

    The final code (setRandomLatLon takes in V8 around 120 ms over 10000000 iterations):

    var out = document.getElementById("output")
    
    var start, temp,
        lat1, lat2, lon1, lon2,
        steps = 10000000
    
    function setRandomLatLon(){
        rand = Math.floor(Math.random()*12);
        lat1 = rand + 2
        lat2 = rand + 12
        lon1 = rand + 4
        lon2 = rand + 14
    }
    
    // pythagoras    
    
    start = Date.now()
    
    for(var i = 0; i < steps; i++) {
        setRandomLatLon()
        temp = Math.sqrt(lat2)
    }
    
    out.innerHTML += '<div> sqrt : ' + (Date.now() - start) + '</div>'
    
    // pythagoras
    
    start = Date.now();
    
    for(var i = 0; i < steps; i++) {
        setRandomLatLon()
        temp = Math.sqrt(Math.pow(lat2 - lat1, 2) + Math.pow(lon2 - lon1, 2))
    }
    
    out.innerHTML += '<div> pythagoras : ' + (Date.now() - start) + '</div>'