Cython Basics#
References#
Installation#
[3]:
!pip install cython
Requirement already satisfied: cython in /workspaces/LearningPython/.venv/lib/python3.12/site-packages (3.0.11)
Setup#
[1]:
import cython
from time import time
[ ]:
def timeit(func):
def inner(*args, **kwargs):
start = time()
result = func(*args, **kwargs)
end = time()
print(f"function : {func.__name__} | time taken : {end-start}")
return result
return inner
[2]:
%load_ext Cython
Comparative Example#
[12]:
%%cython --annotate
def print_prime_number_cython(int last):
cdef int digit,is_prime,cursor
digit = 2
while digit <= last :
is_prime = 1
cursor = 2
while cursor <= digit/2:
if digit % cursor == 0:
is_prime = 0
break
cursor += 1
# if is_prime:
# print(digit)
digit += 1
[12]:
Generated by Cython 3.0.11
Yellow lines hint at Python interaction.
Click on a line that starts with a "+" to see the C code that Cython generated for it.
01:
+02: def print_prime_number_cython(int last):
/* Python wrapper */
static PyObject *__pyx_pw_54_cython_magic_2a3b2141e08b9da09a810877feabca7fd49e51c9_1print_prime_number_cython(PyObject *__pyx_self,
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
static PyMethodDef __pyx_mdef_54_cython_magic_2a3b2141e08b9da09a810877feabca7fd49e51c9_1print_prime_number_cython = {"print_prime_number_cython", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_54_cython_magic_2a3b2141e08b9da09a810877feabca7fd49e51c9_1print_prime_number_cython, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_54_cython_magic_2a3b2141e08b9da09a810877feabca7fd49e51c9_1print_prime_number_cython(PyObject *__pyx_self,
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
int __pyx_v_last;
#if !CYTHON_METH_FASTCALL
CYTHON_UNUSED Py_ssize_t __pyx_nargs;
#endif
CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("print_prime_number_cython (wrapper)", 0);
#if !CYTHON_METH_FASTCALL
#if CYTHON_ASSUME_SAFE_MACROS
__pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
#else
__pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
#endif
#endif
__pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
{
PyObject **__pyx_pyargnames[] = {&__pyx_n_s_last,0};
PyObject* values[1] = {0};
if (__pyx_kwds) {
Py_ssize_t kw_args;
switch (__pyx_nargs) {
case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
CYTHON_FALLTHROUGH;
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
switch (__pyx_nargs) {
case 0:
if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_last)) != 0)) {
(void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
kw_args--;
}
else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2, __pyx_L3_error)
else goto __pyx_L5_argtuple_error;
}
if (unlikely(kw_args > 0)) {
const Py_ssize_t kwd_pos_args = __pyx_nargs;
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "print_prime_number_cython") < 0)) __PYX_ERR(0, 2, __pyx_L3_error)
}
} else if (unlikely(__pyx_nargs != 1)) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
}
__pyx_v_last = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_last == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 2, __pyx_L3_error)
}
goto __pyx_L6_skip;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("print_prime_number_cython", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 2, __pyx_L3_error)
__pyx_L6_skip:;
goto __pyx_L4_argument_unpacking_done;
__pyx_L3_error:;
{
Py_ssize_t __pyx_temp;
for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
__Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
}
}
__Pyx_AddTraceback("_cython_magic_2a3b2141e08b9da09a810877feabca7fd49e51c9.print_prime_number_cython", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_54_cython_magic_2a3b2141e08b9da09a810877feabca7fd49e51c9_print_prime_number_cython(__pyx_self, __pyx_v_last);
int __pyx_lineno = 0;
const char *__pyx_filename = NULL;
int __pyx_clineno = 0;
/* function exit code */
{
Py_ssize_t __pyx_temp;
for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
__Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
}
}
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_54_cython_magic_2a3b2141e08b9da09a810877feabca7fd49e51c9_print_prime_number_cython(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_last) {
int __pyx_v_digit;
CYTHON_UNUSED int __pyx_v_is_prime;
int __pyx_v_cursor;
PyObject *__pyx_r = NULL;
/* … */
/* function exit code */
__pyx_r = Py_None; __Pyx_INCREF(Py_None);
goto __pyx_L0;
__pyx_L1_error:;
__Pyx_AddTraceback("_cython_magic_2a3b2141e08b9da09a810877feabca7fd49e51c9.print_prime_number_cython", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple_ = PyTuple_Pack(4, __pyx_n_s_last, __pyx_n_s_digit, __pyx_n_s_is_prime, __pyx_n_s_cursor); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 2, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple_);
__Pyx_GIVEREF(__pyx_tuple_);
/* … */
__pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_54_cython_magic_2a3b2141e08b9da09a810877feabca7fd49e51c9_1print_prime_number_cython, 0, __pyx_n_s_print_prime_number_cython, NULL, __pyx_n_s_cython_magic_2a3b2141e08b9da09a, __pyx_d, ((PyObject *)__pyx_codeobj__2)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_print_prime_number_cython, __pyx_t_2) < 0) __PYX_ERR(0, 2, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) __PYX_ERR(0, 2, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
03:
04: cdef int digit,is_prime,cursor
05:
+06: digit = 2
__pyx_v_digit = 2;
+07: while digit <= last :
while (1) {
__pyx_t_1 = (__pyx_v_digit <= __pyx_v_last);
if (!__pyx_t_1) break;
08:
+09: is_prime = 1
__pyx_v_is_prime = 1;
+10: cursor = 2
__pyx_v_cursor = 2;
+11: while cursor <= digit/2:
while (1) {
__pyx_t_1 = (__pyx_v_cursor <= (((double)__pyx_v_digit) / 2.0));
if (!__pyx_t_1) break;
12:
+13: if digit % cursor == 0:
if (unlikely(__pyx_v_cursor == 0)) {
PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
__PYX_ERR(0, 13, __pyx_L1_error)
}
__pyx_t_1 = (__Pyx_mod_int(__pyx_v_digit, __pyx_v_cursor) == 0);
if (__pyx_t_1) {
/* … */
}
+14: is_prime = 0
__pyx_v_is_prime = 0;
+15: break
goto __pyx_L6_break;
16:
+17: cursor += 1
__pyx_v_cursor = (__pyx_v_cursor + 1);
}
__pyx_L6_break:;
18:
19:
20: # if is_prime:
21: # print(digit)
22:
+23: digit += 1
__pyx_v_digit = (__pyx_v_digit + 1); }
[13]:
def print_prime_number_python(last):
digit = 2
while digit <= last :
is_prime = True
cursor = 2
while cursor <= digit/2:
if digit % cursor == 0:
is_prime = False
break
cursor += 1
# if is_prime:
# print(digit)
digit += 1
[15]:
timeit(print_prime_number_python)(100000)
timeit(print_prime_number_cython)(100000)
function : print_prime_number_python | time taken : 23.935476303100586
function : print_prime_number_cython | time taken : 0.43451380729675293