{ "cells": [ { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "import ctypes\n", "import math as m\n", "from ctypes.util import find_library" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "# Windows .dll\n", "# Linux .so" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(0.8414709848078965, 0.8414709848078965)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "libm = ctypes.CDLL(find_library('m'))\n", "csin = libm.sin\n", "csin.restype = ctypes.c_double\n", "x = ctypes.c_double(1.0)\n", "csin(x), m.sin(1.0)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "322 ns ± 2.69 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n", "131 ns ± 0.565 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n" ] } ], "source": [ "x_c = ctypes.c_double(1.0)\n", "x_py = 1.0\n", "%timeit csin(x_c)\n", "%timeit m.sin(x_py)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Mon Dec 14 13:25:33 2020'" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from time import ctime\n", "libc = ctypes.CDLL(find_library('c'))\n", "ctime(libc.time(None))" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "%load_ext cython" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "59.3 ms ± 187 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "62 ms ± 3.07 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "from cymodule.pymodule import golden_ratio as cythonize_golden_ratio\n", "%timeit cythonize_golden_ratio(1_000_000)\n", "\n", "from pymodule import golden_ratio as golden_ratio\n", "%timeit golden_ratio(1_000_000)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.0\n" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "
\n", " \n", "Generated by Cython 0.29.15
\n", "\n",
" Yellow lines hint at Python interaction.
\n",
" Click on a line that starts with a \"+
\" to see the C code that Cython generated for it.\n",
"
1:
\n",
"+2: def f(x):\n", "
/* Python wrapper */\n", "static PyObject *__pyx_pw_46_cython_magic_a25cc206250de381ca3f21379ccb32a8_1f(PyObject *__pyx_self, PyObject *__pyx_v_x); /*proto*/\n", "static PyMethodDef __pyx_mdef_46_cython_magic_a25cc206250de381ca3f21379ccb32a8_1f = {\"f\", (PyCFunction)__pyx_pw_46_cython_magic_a25cc206250de381ca3f21379ccb32a8_1f, METH_O, 0};\n", "static PyObject *__pyx_pw_46_cython_magic_a25cc206250de381ca3f21379ccb32a8_1f(PyObject *__pyx_self, PyObject *__pyx_v_x) {\n", " PyObject *__pyx_r = 0;\n", " __Pyx_RefNannyDeclarations\n", " __Pyx_RefNannySetupContext(\"f (wrapper)\", 0);\n", " __pyx_r = __pyx_pf_46_cython_magic_a25cc206250de381ca3f21379ccb32a8_f(__pyx_self, ((PyObject *)__pyx_v_x));\n", "\n", " /* function exit code */\n", " __Pyx_RefNannyFinishContext();\n", " return __pyx_r;\n", "}\n", "\n", "static PyObject *__pyx_pf_46_cython_magic_a25cc206250de381ca3f21379ccb32a8_f(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x) {\n", " double __pyx_v_y;\n", " double __pyx_v_z;\n", " PyObject *__pyx_r = NULL;\n", " __Pyx_RefNannyDeclarations\n", " __Pyx_RefNannySetupContext(\"f\", 0);\n", "/* … */\n", " /* function exit code */\n", " __pyx_L1_error:;\n", " __Pyx_XDECREF(__pyx_t_1);\n", " __Pyx_XDECREF(__pyx_t_2);\n", " __Pyx_AddTraceback(\"_cython_magic_a25cc206250de381ca3f21379ccb32a8.f\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", " __pyx_r = NULL;\n", " __pyx_L0:;\n", " __Pyx_XGIVEREF(__pyx_r);\n", " __Pyx_RefNannyFinishContext();\n", " return __pyx_r;\n", "}\n", "/* … */\n", " __pyx_tuple_ = PyTuple_Pack(3, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_z); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 2, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_tuple_);\n", " __Pyx_GIVEREF(__pyx_tuple_);\n", "/* … */\n", " __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_a25cc206250de381ca3f21379ccb32a8_1f, NULL, __pyx_n_s_cython_magic_a25cc206250de381ca); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_1);\n", " if (PyDict_SetItem(__pyx_d, __pyx_n_s_f, __pyx_t_1) < 0) __PYX_ERR(0, 2, __pyx_L1_error)\n", " __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n", " __pyx_codeobj__2 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple_, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_jovyan_cache_ipython_cytho, __pyx_n_s_f, 2, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__2)) __PYX_ERR(0, 2, __pyx_L1_error)\n", "
+3: cdef double y = 1.0\n", "
__pyx_v_y = 1.0;\n", "
+4: cdef double z = x + y\n", "
__pyx_t_1 = PyFloat_FromDouble(__pyx_v_y); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_1);\n", " __pyx_t_2 = PyNumber_Add(__pyx_v_x, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_2);\n", " __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n", " __pyx_t_3 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_3 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 4, __pyx_L1_error)\n", " __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;\n", " __pyx_v_z = __pyx_t_3;\n", "
+5: return z\n", "
__Pyx_XDECREF(__pyx_r);\n", " __pyx_t_2 = PyFloat_FromDouble(__pyx_v_z); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 5, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_2);\n", " __pyx_r = __pyx_t_2;\n", " __pyx_t_2 = 0;\n", " goto __pyx_L0;\n", "
6:
\n",
"+7: print(f(2))\n", "
__Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_f); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_1);\n", " __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_2);\n", " __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n", " __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_1);\n", " __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;\n", " __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n", "