Cython:Typed memoryviews

例子

这里 double[::1] 是一种 memoryview 方法,效率跟 Numpy 数组差不多,可以给 C 数组赋值,可以给 Numpy 数组赋值,可以像 Numpy 一样切片:

In [1]:

  1. %%file cython_sum.pyx
  2. def cython_sum(double[::1] a):
  3. cdef double s = 0.0
  4. cdef int i, n = a.shape[0]
  5. for i in range(n):
  6. s += a[i]
  7. return s
  1. Writing cython_sum.pyx

In [2]:

  1. %%file setup.py
  2. from distutils.core import setup
  3. from distutils.extension import Extension
  4. from Cython.Distutils import build_ext
  5.  
  6. ext = Extension("cython_sum", ["cython_sum.pyx"])
  7.  
  8. setup(
  9. cmdclass = {'build_ext': build_ext},
  10. ext_modules = [ext],
  11. )
  1. Writing setup.py

In [3]:

  1. !python setup.py build_ext -i
  1. running build_ext
  2. cythoning cython_sum.pyx to cython_sum.c
  3. building 'cython_sum' extension
  4. creating build
  5. creating build\temp.win-amd64-2.7
  6. creating build\temp.win-amd64-2.7\Release
  7. 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
  8. writing build\temp.win-amd64-2.7\Release\cython_sum.def
  9. 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"
  1. cython_sum.c: In function '__Pyx_BufFmt_ProcessTypeChunk':
  2. cython_sum.c:13561:26: warning: unknown conversion type character 'z' in format [-Wformat]
  3. cython_sum.c:13561:26: warning: unknown conversion type character 'z' in format [-Wformat]
  4. cython_sum.c:13561:26: warning: too many arguments for format [-Wformat-extra-args]
  5. cython_sum.c:13613:20: warning: unknown conversion type character 'z' in format [-Wformat]
  6. cython_sum.c:13613:20: warning: unknown conversion type character 'z' in format [-Wformat]
  7. cython_sum.c:13613:20: warning: too many arguments for format [-Wformat-extra-args]
  8. cython_sum.c: In function '__pyx_buffmt_parse_array':
  9. cython_sum.c:13675:25: warning: unknown conversion type character 'z' in format [-Wformat]
  10. cython_sum.c:13675:25: warning: format '%d' expects argument of type 'int', but argument 3 has type 'size_t' [-Wformat]
  11. cython_sum.c:13675:25: warning: too many arguments for format [-Wformat-extra-args]
  12. cython_sum.c: In function '__Pyx_GetBufferAndValidate':
  13. cython_sum.c:13860:7: warning: unknown conversion type character 'z' in format [-Wformat]
  14. cython_sum.c:13860:7: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'Py_ssize_t' [-Wformat]
  15. cython_sum.c:13860:7: warning: unknown conversion type character 'z' in format [-Wformat]
  16. cython_sum.c:13860:7: warning: too many arguments for format [-Wformat-extra-args]
  17. cython_sum.c: In function '__Pyx_RaiseArgtupleInvalid':
  18. cython_sum.c:14032:18: warning: unknown conversion type character 'z' in format [-Wformat]
  19. cython_sum.c:14032:18: warning: format '%s' expects argument of type 'char *', but argument 5 has type 'Py_ssize_t' [-Wformat]
  20. cython_sum.c:14032:18: warning: unknown conversion type character 'z' in format [-Wformat]
  21. cython_sum.c:14032:18: warning: too many arguments for format [-Wformat-extra-args]
  22. cython_sum.c: In function '__Pyx_RaiseTooManyValuesError':
  23. cython_sum.c:14552:18: warning: unknown conversion type character 'z' in format [-Wformat]
  24. cython_sum.c:14552:18: warning: too many arguments for format [-Wformat-extra-args]
  25. cython_sum.c: In function '__Pyx_RaiseNeedMoreValuesError':
  26. cython_sum.c:14558:18: warning: unknown conversion type character 'z' in format [-Wformat]
  27. cython_sum.c:14558:18: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'Py_ssize_t' [-Wformat]
  28. cython_sum.c:14558:18: warning: too many arguments for format [-Wformat-extra-args]
  29. cython_sum.c: In function '__Pyx_ValidateAndInit_memviewslice':
  30. cython_sum.c:15253:22: warning: unknown conversion type character 'z' in format [-Wformat]
  31. cython_sum.c:15253:22: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'Py_ssize_t' [-Wformat]
  32. cython_sum.c:15253:22: warning: unknown conversion type character 'z' in format [-Wformat]
  33. cython_sum.c:15253:22: warning: too many arguments for format [-Wformat-extra-args]

In [4]:

  1. from cython_sum import cython_sum
  2. from numpy import *

In [5]:

  1. a = arange(1e6)

检查正确性:

In [6]:

  1. cython_sum(a)

Out[6]:

  1. 499999500000.0

In [7]:

  1. a.sum()

Out[7]:

  1. 499999500000.0

效率:

In [8]:

  1. %timeit cython_sum(a)
  1. 100 loops, best of 3: 2.14 ms per loop

In [9]:

  1. %timeit a.sum()
  1. 100 loops, best of 3: 2.38 ms per loop

In [10]:

  1. import zipfile
  2.  
  3. f = zipfile.ZipFile('07-06-cython-sum.zip','w',zipfile.ZIP_DEFLATED)
  4.  
  5. names = ['cython_sum.pyx',
  6. 'setup.py']
  7. for name in names:
  8. f.write(name)
  9.  
  10. f.close()
  11.  
  12. !rm -f setup*.*
  13. !rm -f cython_sum*.*
  14. !rm -rf build

原文: https://nbviewer.jupyter.org/github/lijin-THU/notes-python/blob/master/07-interfacing-with-other-languages/07.06-cython-part-4.ipynb