# Cython三分钟入门

import math

def great_circle(lon1,lat1,lon2,lat2):
x = math.pi/180.0

a = (90.0-lat1)*(x)
b = (90.0-lat2)*(x)
theta = (lon2-lon1)*(x)
c = math.acos((math.cos(a)*math.cos(b)) +
(math.sin(a)*math.sin(b)*math.cos(theta)))
return radius*c

import timeit

lon1, lat1, lon2, lat2 = -72.345, 34.323, -61.823, 54.826
num = 500000

t = timeit.Timer("p1.great_circle(%f,%f,%f,%f)" % (lon1,lat1,lon2,lat2),
"import p1")
print "Pure python function", t.timeit(num), "sec"

2.2 。它太慢了！

import math

def great_circle(float lon1,float lat1,float lon2,float lat2):
cdef float pi = 3.14159265
cdef float x = pi/180.0
cdef float a,b,theta,c

a = (90.0-lat1)*(x)
b = (90.0-lat2)*(x)
theta = (lon2-lon1)*(x)
c = math.acos((math.cos(a)*math.cos(b)) + (math.sin(a)*math.sin(b)*math.cos(theta)))
return radius*c

# this will create a c1.c file - the C source code to build a python extension
cython c1.pyx

# Compile the object file
gcc -c -fPIC -I/usr/include/python2.5/ c1.c

# Link it into a shared library
gcc -shared c1.o -o c1.so

    t = timeit.Timer("c1.great_circle(%f,%f,%f,%f)" % (lon1,lat1,lon2,lat2),
"import c1")
print "Cython function (still using python math)", t.timeit(num), "sec"

1.8 。并没有我们一开始期望的那种大大的性能提升。使用 python math 模块应该是瓶颈。现在让我们使用C标准库替代之：

cdef extern from "math.h":
float cosf(float theta)
float sinf(float theta)
float acosf(float theta)

def great_circle(float lon1,float lat1,float lon2,float lat2):
cdef float pi = 3.14159265
cdef float x = pi/180.0
cdef float a,b,theta,c

a = (90.0-lat1)*(x)
b = (90.0-lat2)*(x)
theta = (lon2-lon1)*(x)
c = acosf((cosf(a)*cosf(b)) + (sinf(a)*sinf(b)*cosf(theta)))
return radius*c

import math 相应，我们使用cdef extern 的方式使用从指定头文件声明函数（在此就是使用C标准库的math.h）。我们替代了代价高昂的的Python函数，然后建立新的共享库，并重新测试：

    t = timeit.Timer("c2.great_circle(%f,%f,%f,%f)" % (lon1,lat1,lon2,lat2),
"import c2")
print "Cython function (using trig function from math.h)", t.timeit(num), "sec"

cdef extern from "math.h":
float cosf(float theta)
float sinf(float theta)
float acosf(float theta)

cdef float _great_circle(float lon1,float lat1,float lon2,float lat2):
cdef float pi = 3.14159265
cdef float x = pi/180.0
cdef float a,b,theta,c

a = (90.0-lat1)*(x)
b = (90.0-lat2)*(x)
theta = (lon2-lon1)*(x)
c = acosf((cosf(a)*cosf(b)) + (sinf(a)*sinf(b)*cosf(theta)))

def great_circle(float lon1,float lat1,float lon2,float lat2,int num):
cdef int i
cdef float x
for i from 0 < = i < num:
x = _great_circle(lon1,lat1,lon2,lat2)
return x

#include <math .h>
#include <stdio .h>
#define NUM 500000

float great_circle(float lon1, float lat1, float lon2, float lat2){
float pi = 3.14159265;
float x = pi/180.0;
float a,b,theta,c;

a = (90.0-lat1)*(x);
b = (90.0-lat2)*(x);
theta = (lon2-lon1)*(x);
c = acos((cos(a)*cos(b)) + (sin(a)*sin(b)*cos(theta)));
}

int main() {
int i;
float x;
for (i=0; i < = NUM; i++)
x = great_circle(-72.345, 34.323, -61.823, 54.826);
printf("%f", x);
}

gcc -lm -octest ctest.c编译它，测试用time./ctest ...大约0.2 。这使我有信心，我Cython扩展相对于我的C代码也极有效率（这并不是说我的C编程能力很弱）。

"我们应该忘记小的效率，过早的优化是一切罪恶的根源，有 97% 的案例如此。"——DonaldKnuth

WorldMill
http://trac.gispython.org/projects/PCL/wiki/WorldMill——Sean Gillies Cython 编写的一个快速的，提供简洁的 python 接口的模块，封装了用以处理矢量地理空间数据的 libgdal 库。