Cython:Typed memoryviews
例子
这里 double[::1]
是一种 memoryview
方法,效率跟 Numpy
数组差不多,可以给 C
数组赋值,可以给 Numpy
数组赋值,可以像 Numpy
一样切片:
In [1]:
- %%file cython_sum.pyx
- def cython_sum(double[::1] a):
- cdef double s = 0.0
- cdef int i, n = a.shape[0]
- for i in range(n):
- s += a[i]
- return s
- Writing cython_sum.pyx
In [2]:
- %%file setup.py
- from distutils.core import setup
- from distutils.extension import Extension
- from Cython.Distutils import build_ext
- ext = Extension("cython_sum", ["cython_sum.pyx"])
- setup(
- cmdclass = {'build_ext': build_ext},
- ext_modules = [ext],
- )
- Writing setup.py
In [3]:
- !python setup.py build_ext -i
- running build_ext
- cythoning cython_sum.pyx to cython_sum.c
- building 'cython_sum' extension
- creating build
- creating build\temp.win-amd64-2.7
- creating build\temp.win-amd64-2.7\Release
- C:\Anaconda\Scripts\gcc.bat -DMS_WIN64 -mdll -O -Wall -IC:\Anaconda\include -IC:\Anaconda\PC -c cython_sum.c -o build\temp.win-amd64-2.7\Release\cython_sum.o
- writing build\temp.win-amd64-2.7\Release\cython_sum.def
- C:\Anaconda\Scripts\gcc.bat -DMS_WIN64 -shared -s build\temp.win-amd64-2.7\Release\cython_sum.o build\temp.win-amd64-2.7\Release\cython_sum.def -LC:\Anaconda\libs -LC:\Anaconda\PCbuild\amd64 -lpython27 -lmsvcr90 -o "C:\Users\lijin\Documents\Git\python-tutorial\07. interfacing with other languages\cython_sum.pyd"
- cython_sum.c: In function '__Pyx_BufFmt_ProcessTypeChunk':
- cython_sum.c:13561:26: warning: unknown conversion type character 'z' in format [-Wformat]
- cython_sum.c:13561:26: warning: unknown conversion type character 'z' in format [-Wformat]
- cython_sum.c:13561:26: warning: too many arguments for format [-Wformat-extra-args]
- cython_sum.c:13613:20: warning: unknown conversion type character 'z' in format [-Wformat]
- cython_sum.c:13613:20: warning: unknown conversion type character 'z' in format [-Wformat]
- cython_sum.c:13613:20: warning: too many arguments for format [-Wformat-extra-args]
- cython_sum.c: In function '__pyx_buffmt_parse_array':
- cython_sum.c:13675:25: warning: unknown conversion type character 'z' in format [-Wformat]
- cython_sum.c:13675:25: warning: format '%d' expects argument of type 'int', but argument 3 has type 'size_t' [-Wformat]
- cython_sum.c:13675:25: warning: too many arguments for format [-Wformat-extra-args]
- cython_sum.c: In function '__Pyx_GetBufferAndValidate':
- cython_sum.c:13860:7: warning: unknown conversion type character 'z' in format [-Wformat]
- cython_sum.c:13860:7: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'Py_ssize_t' [-Wformat]
- cython_sum.c:13860:7: warning: unknown conversion type character 'z' in format [-Wformat]
- cython_sum.c:13860:7: warning: too many arguments for format [-Wformat-extra-args]
- cython_sum.c: In function '__Pyx_RaiseArgtupleInvalid':
- cython_sum.c:14032:18: warning: unknown conversion type character 'z' in format [-Wformat]
- cython_sum.c:14032:18: warning: format '%s' expects argument of type 'char *', but argument 5 has type 'Py_ssize_t' [-Wformat]
- cython_sum.c:14032:18: warning: unknown conversion type character 'z' in format [-Wformat]
- cython_sum.c:14032:18: warning: too many arguments for format [-Wformat-extra-args]
- cython_sum.c: In function '__Pyx_RaiseTooManyValuesError':
- cython_sum.c:14552:18: warning: unknown conversion type character 'z' in format [-Wformat]
- cython_sum.c:14552:18: warning: too many arguments for format [-Wformat-extra-args]
- cython_sum.c: In function '__Pyx_RaiseNeedMoreValuesError':
- cython_sum.c:14558:18: warning: unknown conversion type character 'z' in format [-Wformat]
- cython_sum.c:14558:18: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'Py_ssize_t' [-Wformat]
- cython_sum.c:14558:18: warning: too many arguments for format [-Wformat-extra-args]
- cython_sum.c: In function '__Pyx_ValidateAndInit_memviewslice':
- cython_sum.c:15253:22: warning: unknown conversion type character 'z' in format [-Wformat]
- cython_sum.c:15253:22: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'Py_ssize_t' [-Wformat]
- cython_sum.c:15253:22: warning: unknown conversion type character 'z' in format [-Wformat]
- cython_sum.c:15253:22: warning: too many arguments for format [-Wformat-extra-args]
In [4]:
- from cython_sum import cython_sum
- from numpy import *
In [5]:
- a = arange(1e6)
检查正确性:
In [6]:
- cython_sum(a)
Out[6]:
- 499999500000.0
In [7]:
- a.sum()
Out[7]:
- 499999500000.0
效率:
In [8]:
- %timeit cython_sum(a)
- 100 loops, best of 3: 2.14 ms per loop
In [9]:
- %timeit a.sum()
- 100 loops, best of 3: 2.38 ms per loop
In [10]:
- import zipfile
- f = zipfile.ZipFile('07-06-cython-sum.zip','w',zipfile.ZIP_DEFLATED)
- names = ['cython_sum.pyx',
- 'setup.py']
- for name in names:
- f.write(name)
- f.close()
- !rm -f setup*.*
- !rm -f cython_sum*.*
- !rm -rf build