{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Cython:Typed memoryviews" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 例子" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "这里 `double[::1]` 是一种 `memoryview` 方法,效率跟 `Numpy` 数组差不多,可以给 `C` 数组赋值,可以给 `Numpy` 数组赋值,可以像 `Numpy` 一样切片:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Writing cython_sum.pyx\n" ] } ], "source": [ "%%file cython_sum.pyx\n", "def cython_sum(double[::1] a):\n", " cdef double s = 0.0\n", " cdef int i, n = a.shape[0]\n", " for i in range(n):\n", " s += a[i]\n", " return s" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Writing setup.py\n" ] } ], "source": [ "%%file setup.py\n", "from distutils.core import setup\n", "from distutils.extension import Extension\n", "from Cython.Distutils import build_ext\n", "\n", "ext = Extension(\"cython_sum\", [\"cython_sum.pyx\"])\n", "\n", "setup(\n", " cmdclass = {'build_ext': build_ext},\n", " ext_modules = [ext],\n", ")" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "running build_ext\n", "cythoning cython_sum.pyx to cython_sum.c\n", "building 'cython_sum' extension\n", "creating build\n", "creating build\\temp.win-amd64-2.7\n", "creating build\\temp.win-amd64-2.7\\Release\n", "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\n", "writing build\\temp.win-amd64-2.7\\Release\\cython_sum.def\n", "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\"\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "cython_sum.c: In function '__Pyx_BufFmt_ProcessTypeChunk':\n", "cython_sum.c:13561:26: warning: unknown conversion type character 'z' in format [-Wformat]\n", "cython_sum.c:13561:26: warning: unknown conversion type character 'z' in format [-Wformat]\n", "cython_sum.c:13561:26: warning: too many arguments for format [-Wformat-extra-args]\n", "cython_sum.c:13613:20: warning: unknown conversion type character 'z' in format [-Wformat]\n", "cython_sum.c:13613:20: warning: unknown conversion type character 'z' in format [-Wformat]\n", "cython_sum.c:13613:20: warning: too many arguments for format [-Wformat-extra-args]\n", "cython_sum.c: In function '__pyx_buffmt_parse_array':\n", "cython_sum.c:13675:25: warning: unknown conversion type character 'z' in format [-Wformat]\n", "cython_sum.c:13675:25: warning: format '%d' expects argument of type 'int', but argument 3 has type 'size_t' [-Wformat]\n", "cython_sum.c:13675:25: warning: too many arguments for format [-Wformat-extra-args]\n", "cython_sum.c: In function '__Pyx_GetBufferAndValidate':\n", "cython_sum.c:13860:7: warning: unknown conversion type character 'z' in format [-Wformat]\n", "cython_sum.c:13860:7: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'Py_ssize_t' [-Wformat]\n", "cython_sum.c:13860:7: warning: unknown conversion type character 'z' in format [-Wformat]\n", "cython_sum.c:13860:7: warning: too many arguments for format [-Wformat-extra-args]\n", "cython_sum.c: In function '__Pyx_RaiseArgtupleInvalid':\n", "cython_sum.c:14032:18: warning: unknown conversion type character 'z' in format [-Wformat]\n", "cython_sum.c:14032:18: warning: format '%s' expects argument of type 'char *', but argument 5 has type 'Py_ssize_t' [-Wformat]\n", "cython_sum.c:14032:18: warning: unknown conversion type character 'z' in format [-Wformat]\n", "cython_sum.c:14032:18: warning: too many arguments for format [-Wformat-extra-args]\n", "cython_sum.c: In function '__Pyx_RaiseTooManyValuesError':\n", "cython_sum.c:14552:18: warning: unknown conversion type character 'z' in format [-Wformat]\n", "cython_sum.c:14552:18: warning: too many arguments for format [-Wformat-extra-args]\n", "cython_sum.c: In function '__Pyx_RaiseNeedMoreValuesError':\n", "cython_sum.c:14558:18: warning: unknown conversion type character 'z' in format [-Wformat]\n", "cython_sum.c:14558:18: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'Py_ssize_t' [-Wformat]\n", "cython_sum.c:14558:18: warning: too many arguments for format [-Wformat-extra-args]\n", "cython_sum.c: In function '__Pyx_ValidateAndInit_memviewslice':\n", "cython_sum.c:15253:22: warning: unknown conversion type character 'z' in format [-Wformat]\n", "cython_sum.c:15253:22: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'Py_ssize_t' [-Wformat]\n", "cython_sum.c:15253:22: warning: unknown conversion type character 'z' in format [-Wformat]\n", "cython_sum.c:15253:22: warning: too many arguments for format [-Wformat-extra-args]\n" ] } ], "source": [ "!python setup.py build_ext -i" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from cython_sum import cython_sum\n", "from numpy import *" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "a = arange(1e6)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "检查正确性:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "499999500000.0" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cython_sum(a)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "499999500000.0" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.sum()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "效率:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "100 loops, best of 3: 2.14 ms per loop\n" ] } ], "source": [ "%timeit cython_sum(a)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "100 loops, best of 3: 2.38 ms per loop\n" ] } ], "source": [ "%timeit a.sum()" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import zipfile\n", "\n", "f = zipfile.ZipFile('07-06-cython-sum.zip','w',zipfile.ZIP_DEFLATED)\n", "\n", "names = ['cython_sum.pyx',\n", " 'setup.py']\n", "for name in names:\n", " f.write(name)\n", "\n", "f.close()\n", "\n", "!rm -f setup*.*\n", "!rm -f cython_sum*.*\n", "!rm -rf build" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.10" } }, "nbformat": 4, "nbformat_minor": 0 }