I recently stumbled across the GoPy module that makes it dead easy to convert any Golang package into a Python module.
Here's how you would use it
go get github.com/jonathan-kosgei/geodist gopy build -output=geodist -vm=python3 github.com/jonathan-kosgei/geodist
then you can import the module in Python
>> from geodist import geodist >> dir(geodist) ['Coord', 'VincentyDistance', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_collections_abc', '_geodist', 'collections', 'currentdir', 'cwd', 'go', 'inspect', 'os', 'sys']
Naturally I was curious whether Python extensions written in Golang have comparable performance to those written in C, which is what we explore in this post.
I'll be testing the Vincenty algorithm for calculating the distance between 2 co-ordinates using:
1. Native Python - using the geopy module
2. Golang extension created with GoPy - I forked John Taylor's geodist package and slightly modified it to make it compatible with GoPy
3. C extension - using uvincenty
Here are the results using iPython
>> from geodist import geodist >> import uvincenty >> import geopy.distance >> boston_go = geodist.Coord(42.3541165, -71.0693514) >> newyork_go = geodist.Coord(40.7791472, -73.9680804) >> %timeit geodist.VincentyDistance(boston_go, newyork_go) 6.24 µs ± 29.2 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) >> boston = (42.3541165, -71.0693514) >> newyork = (40.7791472, -73.9680804) >> %timeit uvincenty.vincenty(*boston, *newyork) 732 ns ± 2.98 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each) >> %timeit geopy.distance.geodesic(boston, newyork) 190 µs ± 1.51 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
The CPython extension (uvincenty) is ~260 times faster than the pure Python implementation from geopy.
The Golang Python extension (geodist) is ~30 times faster than the pure Python implementation.
The CPython extension is 8 times faster than the Golang Python extension.
I'm not certain why the Golang Python extension is slower than the C version given that GoPy generates a CPython extension, my guess is that the generated code is less efficient than the native C approach. However this still shows that a sizeable speedup can be achieved using GoPy generated Python extensions with the added bonus of lowered development time and fewer memory bugs by coding in Golang.