Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Geo distance 2
(version: 0)
Comparing performance of:
Vincenty reference vs Vincenty vs planar vs haversine
Created:
5 years ago
by:
Guest
Jump to the latest result
Script Preparation code:
Benchmark.prototype.setup = function() { /** Converts numeric degrees to radians */ if (typeof(Number.prototype.toRad) === "undefined") { Number.prototype.toRad = function() { return this * Math.PI / 180; } } /** * Calculates geodetic distance between two points specified by latitude/longitude using * Vincenty inverse formula for ellipsoids * * @param {Number} lat1, lon1: first point in decimal degrees * @param {Number} lat2, lon2: second point in decimal degrees * @returns (Number} distance in metres between points */ function distVincentyRef(lat1, lon1, lat2, lon2) { var a = 6378137, b = 6356752.314245, f = 1 / 298.257223563; // WGS-84 ellipsoid params var L = (lon2 - lon1).toRad(); var U1 = Math.atan((1 - f) * Math.tan(lat1.toRad())); var U2 = Math.atan((1 - f) * Math.tan(lat2.toRad())); var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1); var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2); var lambda = L, lambdaP, iterLimit = 100; do { var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda); var sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda)); if (sinSigma == 0) return 0; // co-incident points var cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda; var sigma = Math.atan2(sinSigma, cosSigma); var sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma; var cosSqAlpha = 1 - sinAlpha * sinAlpha; var cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha; if (isNaN(cos2SigmaM)) cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (§6) var C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)); lambdaP = lambda; lambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))); } while (Math.abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0); if (iterLimit == 0) return NaN // formula failed to converge console.log(iterLimit); var uSq = cosSqAlpha * (a * a - b * b) / (b * b); var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq))); var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))); var deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM))); var s = b * A * (sigma - deltaSigma); s = s.toFixed(3); // round to 1mm precision return s; } function distVincenty(lat1, lon1, lat2, lon2) { const a = 6378137, b = 6356752.314245, f = 1 / 298.257223563, // WGS-84 ellipsoid params degToRad = Math.PI / 180, f2 = f * f, f_4_4_16 = (f + f2) / 4, f_3_16 = f2 * 3 / 16, f1 = 1 - f, a2 = a * a, b2 = b * b, a2b2b2 = (a2 - b2) / b2; var L = (lon2 - lon1) * degToRad; var U1 = Math.atan(f1 * Math.tan(lat1 * degToRad)); var U2 = Math.atan(f1 * Math.tan(lat2 * degToRad)); var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1); var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2); var lambda = L, lambdaP, iterLimit = 100; do { var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda); var cosU2sinLambda = cosU2 * sinLambda; var sinU1sinU2 = sinU1 * sinU2; var cosU1sinU2_sinU1cosU2cosLambda = cosU1 * sinU2 - sinU1 * cosU2 * cosLambda; var sinSigma = Math.sqrt(cosU2sinLambda * cosU2sinLambda + cosU1sinU2_sinU1cosU2cosLambda * cosU1sinU2_sinU1cosU2cosLambda); if (sinSigma == 0) return 0; // co-incident points var cosSigma = sinU1sinU2 + cosU1 * cosU2 * cosLambda; var sigma = Math.atan2(sinSigma, cosSigma); var sinAlpha = cosU1 * cosU2sinLambda / sinSigma; var cosSqAlpha = 1 - sinAlpha * sinAlpha; var cos2SigmaM = cosSigma - 2 * sinU1sinU2 / cosSqAlpha; if (isNaN(cos2SigmaM)) cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (§6) var C = cosSqAlpha * (f_4_4_16 - f_3_16 * cosSqAlpha); lambdaP = lambda; lambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))); } while (Math.abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0); if (iterLimit == 0) return NaN // formula failed to converge console.log(iterLimit); var uSq = cosSqAlpha * a2b2b2; var A = 1 + uSq * (0.25 + uSq * (-0.046875 + uSq * (0.01953125 - 0.01068115234 * uSq))); var B = uSq * (0.25 + uSq * (-0.125 + uSq * (0.072265625 - 0.0458984375 * uSq))); var deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM))); var s = b * A * (sigma - deltaSigma); s = s.toFixed(3); // round to 1mm precision return s; } function distPlanar(latDeg1, lonDeg1, latDeg2, lonDeg2) { const a = 6378137, b = 6356752.314245, a2 = a * a, b2 = b * b, ab4 = a2 * a2 * b2 * b2; var latRad1 = latDeg1 / 180.0 * Math.PI; var lonRad1 = lonDeg1 / 180.0 * Math.PI; var latRad2 = latDeg2 / 180.0 * Math.PI; var lonRad2 = lonDeg2 / 180.0 * Math.PI; var latRad = (latRad1 + latRad2) * 0.5; var lonRad = (lonRad1 + lonRad2) * 0.5; var sinLat = Math.sin(latRad); var sinLat2 = sinLat * sinLat; var a2cos2 = a2 * (1 - sinLat2); var b2sin2 = b2 * sinLat2; var s = a2cos2 + b2sin2; var latScale2 = ab4 / (s * s * s); var lonScale2 = a2 / (1 + b2sin2 / a2cos2); var dLat = latRad1 - latRad2; var dLon = lonRad1 - lonRad2; return Math.sqrt(latScale2 * dLat * dLat + lonScale2 * dLon * dLon).toFixed(3); } // Distance in kilometers between two points using the Haversine algo. function haversine(lat1, lon1, lat2, lon2) { var R = 6371; var dLat = (lat2 - lat1).toRad(); var dLong = (lon2 - lon1).toRad(); var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * Math.sin(dLong / 2) * Math.sin(dLong / 2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); var d = R * c; return Math.round(d); } };
Tests:
Vincenty reference
distVincentyRef(-31.965379, 115.822077, -33.85789, 151.214806);
Vincenty
distVincenty(-31.965379, 115.822077, -33.85789, 151.214806);
planar
distPlanar(-31.965379, 115.822077, -33.85789, 151.214806);
haversine
haversine(-31.965379, 115.822077, -33.85789, 151.214806);
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (4)
Previous results
Fork
Test case name
Result
Vincenty reference
Vincenty
planar
haversine
Fastest:
N/A
Slowest:
N/A
Latest run results:
No previous run results
This benchmark does not have any results yet. Be the first one
to run it!
Autogenerated LLM Summary
(model
llama3.2:3b
, generated one year ago):
I'll do my best to help you analyze the code and provide insights. **Code Analysis** The provided code is a JavaScript benchmarking script, which appears to be using various geometric distance calculations (Vincenty, Planar, Haversine) to measure performance. The code defines several functions for calculating distances between points on a sphere (Earth), as well as a main function that runs these benchmarks. Here's a brief summary of the code: 1. **Utility Functions**: * `toRad`: converts degrees to radians. * `distPlanar`, `haversine`, and `distVincenty` calculate distances between points using different formulas. 2. **Benchmark Main Function**: * Takes two pairs of latitude and longitude values as input (e.g., `-31.965379, 115.822077, -33.85789, 151.214806`). * Calculates the distances using each of the three distance functions. * Returns an array with the execution time for each test case. **Key Observations** 1. The `haversine` function appears to be a simplified version of the full Haversine formula, which might lead to inaccuracies or faster performance at the cost of precision. 2. The `distVincenty` and `distPlanar` functions seem to use approximations for the Vincenty distance calculation, which could affect accuracy but potentially improve performance. 3. The main function runs multiple iterations (not shown in the provided code) before returning the results. **Performance Analysis** To analyze the performance of this code, I'd focus on: 1. **Execution Time**: Compare execution times across different browsers and platforms to identify any differences or patterns. 2. **Accuracy**: Verify that the benchmarking script accurately measures distances using each formula. 3. **Parallelization**: Consider whether parallelizing the main function could improve performance by leveraging multiple CPU cores. **Next Steps** If you'd like to dive deeper, here are some potential next steps: 1. **Refine the `haversine` and other functions** to ensure accuracy and optimal performance. 2. **Investigate parallelization techniques**, such as using Web Workers or async/await, to improve execution times. 3. **Run additional tests** to compare performance across different browsers, platforms, and hardware configurations. Please let me know if you'd like me to elaborate on any of these points or explore specific aspects further!
Related benchmarks:
Haversine Distance tests
Geo distance
LatLongDistance
Haversine performance
Comments
Confirm delete:
Do you really want to delete benchmark?