maurycyp / vincenty

Calculate the geographical distance between 2 points with extreme accuracy.
The Unlicense
62 stars 13 forks source link

Add benchmark notes / unittests #2

Open thehesiod opened 7 years ago

thehesiod commented 7 years ago

I've been searching for the fastest geodesic library for python and it seems yours is by far the fastest. This makes me both worried that some edge case is missing and at the same time very impressed :)

If the algorithm is indeed correct I suggest adding unittests and benchmark results to the front page in github.

Here is my benchmark code and results:

import time
from contextlib import contextmanager
from geographiclib.geodesic import Geodesic as geographic_geodesic
import vincenty
import geopy.distance

@contextmanager
def timeit(title, iterations):
    t1 = time.clock()
    yield
    t2 = time.clock()
    elapsed = t2 - t1
    print('%s: elapsed:%0.2fs o/s:%0.2f iterations:%d' % (title, elapsed, iterations / elapsed, iterations))

def time_iter(iterations, func, *args, pre_test=None, **kwargs):
    with timeit("{}.{}".format(func.__module__, func.__name__), iterations):
        for _ in range(iterations):
            if pre_test:
                pre_test()
            val = func(*args, **kwargs)
    print(val)

# latitude/longitude
newport_ri = (41.49008, -71.312796)
cleveland_oh = (41.499498, -81.695391)

def test_geographiclib():
    return geographic_geodesic.WGS84.Inverse(newport_ri[0], newport_ri[1], cleveland_oh[0], cleveland_oh[1], geographic_geodesic.DISTANCE)['s12'] / 1000

def test_geopy():
    return geopy.distance.vincenty(newport_ri, cleveland_oh).kilometers

num_iter = 50000
time_iter(num_iter, test_geopy)
time_iter(num_iter, test_geographiclib)
time_iter(num_iter, vincenty.vincenty, newport_ri, cleveland_oh)

results

__main__.test_geopy: elapsed:0.24s o/s:41574.34 iterations:10000
866.4554329011002
__main__.test_geographiclib: elapsed:1.71s o/s:5854.28 iterations:10000
866.4554329098687
vincenty.vincenty_inverse: elapsed:0.16s o/s:61436.01 iterations:10000
866.455433

as you can see they have similar results, with vincenty reduced by a few decimal digits, however vincenty is 30% faster than geopy and ~10x faster than geographiclib. Btw let me know if you know how to test against the gdist library, would be good to add.

maurycyp commented 7 years ago

Hi @thehesiod . FYI, there are a few doctests that handle some basic edge cases here: https://github.com/maurycyp/vincenty/blob/master/vincenty/__init__.py#L19 .

The algorithm comes from Wikipedia (linked in the README) so there's nothing unusual in my approach.

I'll play with your code and if will add it if everything checks out, thanks!

thehesiod commented 7 years ago

btw here are some testcases: http://geographiclib.sourceforge.net/2009-03/geodesic.html