[pypy-issue] Issue #2493: Unroll map(function, ${fixed width tuple}) (pypy/pypy)

rowillia issues-reply at bitbucket.org
Thu Mar 9 13:04:38 EST 2017


New issue 2493: Unroll map(function, ${fixed width tuple})
https://bitbucket.org/pypy/pypy/issues/2493/unroll-map-function-fixed-width-tuple

rowillia:

I met Phil Jenvey last night at the SF Python meetup and he suggested I file an issue on this:

We've been experimenting with PyPy, and we've got some math-heavy workloads that we've optimized with Cython, for example computing the haversine distance between two lat/lngs, below is a code snippet:  

```python
from math import sin, cos, asin, sqrt

radians_per_degree = 0.0174532925
AVG_EARTH_RADIUS = 6371.0
MILES_PER_KM = 0.621371


def radians(theta):
    return radians_per_degree*theta


def maybe_convert_to_miles(distance, miles):
    if miles:
        return MILES_PER_KM * distance
    else:
        return distance


def _haversine(lat1, lng1, lat2, lng2):
    # convert all latitudes/longitudes from decimal degrees to radians
    lat1, lng1, lat2, lng2 = map(radians, (lat1, lng1, lat2, lng2))

    # calculate haversine
    lat = lat2 - lat1
    lng = lng2 - lng1
    l1 = sin(lat * 0.5)
    l2 = sin(lng * 0.5)
    d = (l1 * l1) + cos(lat1) * cos(lat2) * (l2 * l2)
    return 2 * AVG_EARTH_RADIUS * asin(sqrt(d))

def haversine(point1, point2, miles=0):
    result = _haversine(point1[0], point1[1], point2[0], point2[1])
    return maybe_convert_to_miles(result, miles)
    

LYON = (45.7597, 4.8422)
PARIS = (48.8567, 2.3508)
MUNICH = (48.14287, 11.5770)
```

Last night I noted to Phil that the Cython version running in CPython was 2x faster than the pure python version running in PyPy.  This was actually incorrect, the Cython version manually unrolled ` lat1, lng1, lat2, lng2 = map(radians, (lat1, lng1, lat2, lng2))` into

```python
    lat1 = radians(lat1)
    lng1 = radians(lng1)
    lat2 = radians(lat2)
    lng2 = radians(lng2)
```

Which resulted in a big win.  Doing the same in PyPy resulted in the PyPy code only being 5% slower!

It looks like there might be an opportunity for PyPy to unroll map calls in cases like this where we've got a fixed width tuple.

Thanks for the amazing project!




More information about the pypy-issue mailing list