@@ -26,7 +26,7 @@ Extending Python with Cython
2626 teaching will be given in form of demonstrations and no exercises.
2727 You may still follow along with the code examples but you will need to have
2828 Cython and a working C compiler available. You can install both to your
29- Conda environment with `conda install -c conda-forge cython c-compiler `.
29+ Conda environment with `` conda install -c conda-forge cython c-compiler ` `.
3030
3131
3232Python and performance
@@ -50,11 +50,11 @@ significant overhead. For example, when just adding two integers
5050 the Python interpreter needs to:
5151
5252 1. Check the types of both operands
53- 2. Check whether they both support the ** + ** operation
54- 3. Extract the function that performs the ** + ** operation (due to operator
53+ 2. Check whether they both support the `` + `` operation
54+ 3. Extract the function that performs the `` + `` operation (due to operator
5555 overloading objects can have a custom definition for addition)
5656 4. Extract the actual values of the objects
57- 5. Perform the ** + ** operation
57+ 5. Perform the `` + `` operation
5858 6. Construct a new integer object for the result ("boxing")
5959
6060 .. image :: img/cython/unboxing-boxing.svg
@@ -118,34 +118,34 @@ features that make it possible to generate efficient machine code.
118118Your first Cython module
119119------------------------
120120
121- Suppose we have a Python module called ** my_module.py ** that contains:
121+ Suppose we have a Python module called `` my_module.py `` that contains:
122122
123123.. code :: python
124124
125125 def add (x , y ):
126126 result = x + y
127127 return result
128128
129- Cython allows one to compile ** my_module.py ** directly to machine code while
129+ Cython allows one to compile `` my_module.py `` directly to machine code while
130130still allowing its contents to be imported and used from Python code. We can
131131Cythonize the module "manually" from command line:
132132
133133.. code :: bash
134134
135135 $ cythonize -i my_module.py
136136
137- This produces a file called ** my_module.c ** , full of C code. One can
138- investigate the generated ** .c ** file but it is not really meant for humans to
137+ This produces a file called `` my_module.c `` , full of C code. One can
138+ investigate the generated `` .c `` file but it is not really meant for humans to
139139read, because of all the boilerplate that Cython adds in order to make the
140140compiled code available to Python. Already this simple function results in
141141over 7000 lines of C code!
142142
143- The option ** -i ** (meaning inplace) tells Cython to also compile the generated
144- ** .c ** file into an extension module in the same directory.
143+ The option `` -i `` (meaning inplace) tells Cython to also compile the generated
144+ `` .c `` file into an extension module in the same directory.
145145This could also be done manually by invoking a C-compiler of your choice.
146146On Linux/Mac systems the compiled module will be called something
147- like ** my_module.cpython-314-x86_64-linux-gnu.so ** , on Windows the suffix will
148- be ** .pyd ** .
147+ like `` my_module.cpython-314-x86_64-linux-gnu.so `` , on Windows the suffix will
148+ be `` .pyd `` .
149149
150150The extension module can be imported from Python in the same way as one would
151151import a pure Python module, e.g.:
@@ -158,15 +158,15 @@ import a pure Python module, e.g.:
158158
159159 Usually when working with Cython, one does not Cythonize the whole program but
160160only selected modules. A typical Cython project is separated into plain Python
161- modules (file suffix ** .py ** ), and Cython code files (suffix ** .pyx ** ).
162- The ** .pyx ** files will usually contain Cython-specific code like static type
161+ modules (file suffix `` .py `` ), and Cython code files (suffix `` .pyx `` ).
162+ The `` .pyx `` files will usually contain Cython-specific code like static type
163163information, so that they are not valid Python code anymore and must be
164164Cythonized before use.
165165
166166.. callout ::
167167
168168 Real-world project don't usually invoke Cython from the command line and
169- instead use an established build tool like ** setuptools ** to handle the
169+ instead use an established build tool like `` setuptools `` to handle the
170170 Cythonization during the project's build phase. More info is available on
171171 the `Cython documentation <https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#compilation >`__.
172172 See also the :doc: `course page on packaging <packaging >`.
@@ -188,7 +188,7 @@ We first load the Cython extension, e.g. in the very first cell: ::
188188
189189 %load_ext Cython
190190
191- We can Cythonize cell contents using the magic `%%cython `:
191+ We can Cythonize cell contents using the magic `` %%cython ` `:
192192
193193.. code :: python
194194
@@ -202,7 +202,7 @@ The compiled function can then be called from other cells.
202202
203203.. demo ::
204204
205- There is also `%%cython --annotate `, or `%%cython -a ` for short, which is
205+ There is also `` %%cython --annotate `` , or `` %%cython -a ` ` for short, which is
206206 useful for analyzing the generated C code. Try executing the code for
207207 `add() ` with this magic command in Jupyter. Upon doing so:
208208
@@ -228,7 +228,7 @@ either:
228228
229229- In function signatures by prefixing the formal arguments by their
230230 type.
231- - By declaring variables with the ** cdef ** Cython keyword, followed by
231+ - By declaring variables with the `` cdef `` Cython keyword, followed by
232232 the the type.
233233
234234To make Cython function that adds two integers and returns the result as
@@ -242,7 +242,7 @@ an integer, we would write:
242242 return result
243243
244244 The function works now only with integers but with less boxing/unboxing
245- overhead. Store this as ** my_module.pyx ** (note the file extension) and
245+ overhead. Store this as `` my_module.pyx `` (note the file extension) and
246246Cythonize as before:
247247
248248.. code :: bash
@@ -252,14 +252,14 @@ Cythonize as before:
252252 Import this into Python and confirm that it works as expected with integers.
253253However, if passing floating-point numbers the function is forced to interpret
254254the inputs as integers before performing the addition. For example,
255- ** add(1.4, 2.7) ** would return 3 . This happens because there is an automatic
255+ `` add(1.4, 2.7) `` would return `` 3 `` . This happens because there is an automatic
256256conversion from the input Python objects to the
257257declared C-types, in this case integers, when calling the Cythonized function
258258from Python. Similarly the returned C variable is converted to a corresponding
259259Python object.
260260
261261To make the function work with floats we'd instead declare the types to be
262- either ** float ** (32-bit) or ** double ** (64-bit) type instead of ** int ** .
262+ either `` float `` (32-bit) or `` double `` (64-bit) type instead of `` int `` .
263263The table below lists the most common C types and their corresponding
264264Python types. More information can be found in the `Cython
265265documentation <https://cython.readthedocs.io/en/latest/src/userguide/language_basics.html> `__.
@@ -280,8 +280,8 @@ Cython has built-in support for Numpy arrays.
280280
281281As discussed in the :doc: `Numpy lectures <numpy-advanced >`, Numpy arrays provide
282282great performance for vectorized operations. In contrast, thing like
283- ** for ** -loops over Numpy arrays should be avoided because of interpreting
284- overhead inherent to Python ** for ** -loops. There is also overhead from
283+ `` for `` -loops over Numpy arrays should be avoided because of interpreting
284+ overhead inherent to Python `` for `` -loops. There is also overhead from
285285accessing individual elements of Numpy arrays.
286286
287287With Cython we can bypass both restrictions and write efficient loops over
@@ -302,16 +302,16 @@ Numpy arrays. Consider e.g. a double loop that sets values of a 2D array:
302302 counter += 1
303303
304304
305- We can Cythonize this as before to optimize the ** for ** -loops. A quick check
306- with ** timeit ** shows that with ** N=100 ** , the pure Python version takes 820μs
305+ We can Cythonize this as before to optimize the `` for `` -loops. A quick check
306+ with `` timeit `` shows that with `` N=100 `` , the pure Python version takes 820μs
307307and the Cythonized version (without any static typing) takes 700μs. This is
308308nice, but we are still bottlenecked by array lookups and assignments, i.e. the
309- ** [] ** operator, which invokes Python code.
309+ `` [] `` operator, which invokes Python code.
310310
311311We can get a huge speedup by adding a static type declaration for the Numpy
312312array, and for the other variables too while we are at it. To do this we must
313313import compile-time information about the Numpy module using the
314- Cython-specific ** cimport ** keyword, then use Cython's Numpy interface to
314+ Cython-specific `` cimport `` keyword, then use Cython's Numpy interface to
315315declare the array's datatype and dimensions:
316316
317317.. code :: python
@@ -334,24 +334,24 @@ declare the array's datatype and dimensions:
334334 counter += 1
335335
336336
337- Cythonizing and running the function with ** timeit ** shows that the function
338- now only takes 3.30μs with ** N = 100 ** . This is ~250 times faster than the
337+ Cythonizing and running the function with `` timeit `` shows that the function
338+ now only takes 3.30μs with `` N = 100 `` . This is ~250 times faster than the
339339pure Python implementation!
340340
341341.. callout ::
342342
343- `cimport numpy ` needs access to Numpy C-headers which are usually included
343+ `` cimport numpy ` ` needs access to Numpy C-headers which are usually included
344344 in Python distributions. This usually works out of the box for Jupyter
345- notebooks. However, if using the command line `cythonize ` tool you may need
345+ notebooks. However, if using the command line `` cythonize ` ` tool you may need
346346 to manually set include paths for the C compiler.
347347 Refer to `the docs <https://cython.readthedocs.io/en/latest/src/userguide/numpy_tutorial.html#compilation >`__
348348 for more details.
349349
350350.. callout ::
351351
352- It is good practice to also call `cnp.import_array() ` after doing the
353- `cimport ` of Numpy. This is required for accessing attributes (like
354- `.shape `) of typed Numpy arrays.
352+ It is good practice to also call `` cnp.import_array() ` ` after doing the
353+ `` cimport ` ` of Numpy. This is required for accessing attributes (like
354+ `` .shape ` `) of typed Numpy arrays.
355355
356356
357357More Numpy indexing enhancements
@@ -360,7 +360,7 @@ More Numpy indexing enhancements
360360When indexing arrays, Numpy does some bounds checking in an attempt to catch
361361logic errors (e.g. attempting to access element at index 100 of an array of
362362length 10). Numpy also checks for negative indices to support wraparound
363- syntax like ** a[-1] ** . We can tell Cython to disable these checks for some
363+ syntax like `` a[-1] `` . We can tell Cython to disable these checks for some
364364extra performance:
365365
366366.. code :: python
0 commit comments