我有以下函數使用generator來循環大型座標數組。由於性能非常重要,我嘗試將其轉換爲cython。Python to cython - 改善大型數組迭代的性能
是否有其他更改可以提高性能的cython實現?也許就像使用cpython數組聲明數組或其他?
geometry_converter.pyx:
def esriJson_to_CV(geometry, geometry_type):
def compress_geometry(coords):
cdef int previous_x, previous_y, current_x, current_y
iterator = iter(coords)
previous_x, previous_y = iterator.next()
yield previous_x
yield previous_y
for current_x, current_y in iterator:
yield previous_x - current_x
yield previous_y - current_y
previous_x, previous_y = current_x, current_y
if geometry_type == "POINT":
converted_geometry = [int(geometry["x"]), int(geometry["y"])]
elif geometry_type == "POLYLINE":
converted_geometry = [list(compress_geometry(path)) for path in geometry["paths"]]
elif geometry_type == "POLYGON":
converted_geometry = [list(compress_geometry(ring)) for ring in geometry["rings"]]
else:
raise Exception("geometry_converter.esriJSON_to_CV - {} geometry type not supported".format(geometry_type))
return converted_geometry
基準測試:
import time
from functools import wraps
import numpy as np
import geometry_converter as gc
def timethis(func):
'''
Decorator that reports the execution time.
'''
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(func.__name__, end-start)
return result
return wrapper
def prepare_data(featCount, size):
"""create numpy array with coords and fields"""
input = []
for i in xrange(0, featCount):
polygon = {"rings" : []}
ys = np.random.uniform(0.0,89.0,size).tolist()
xs = np.random.uniform(-179.0,179.0,size).tolist()
polygon["rings"].append(zip(xs,ys))
input.append(polygon)
return input
@timethis
def process_data(data):
output = [gc.esriJson_to_CV(x, "POLYGON") for x in data]
return output
data = prepare_data(1000, 1000000)
out = process_data(data)
print(out[0][0][0:10])
我期望在這類問題中看到Cython實現和基準測試數字。 –
任何對回答這個問題有興趣的人都希望看到一個cython實現。實際數字和測量方法也一樣。 –
因此,您已經更改了問題中的代碼以符合第一個答案的建議,但是如果您在此方面有更好的性能,則不會發表評論。 – jsbueno