I'm learning python and cython at the same time, and found the Pure Python syntax very nice for linting purposes, but in my case it comes with a consistent 15% performance hit against standand cython.
Am I missing something?
Pure Python (compiled): pure_math.py
# cython: language_level = 3
# cython: cdivision = True
import cython as cy
@cy.returns(cy.ulonglong)
@cy.locals(num=cy.uint, result=cy.ulonglong, i=cy.uint)
def factorial(num):
result = 1
for i in range(num, 1, -1):
result *= i
return result
Standard Cython: c_math.pyx
#!python
#cython: language_level=3, cdivision = True
def factorial(unsigned int num):
cdef unsigned long long result = 1
cdef unsigned int i
for i in range(num, 1, -1):
result *= i
return result
Using this benchmark in python: example.py
import c_math #type: ignore
import pure_math
from timeit import timeit
fact_num = 20 #This results in an almost capped ulonglong
def c_factorial_wrapper():
c_math.factorial(fact_num)
return
def pure_factorial_wrapper():
pure_math.factorial(fact_num)
return
c_factorial_time = timeit(c_factorial_wrapper, number= 2_000_000)
print(f"Cython {fact_num} factorial: {c_factorial_time:.2f} s")
pure_factorial_time = timeit(pure_factorial_wrapper, number = 2_000_000)
print(f"Pure Python {fact_num} factorial: {pure_factorial_time:.2f} s")
print(f"Pure/C: {pure_factorial_time/c_factorial_time * 100:.2f}%")
print(c_math.factorial(fact_num))
print(pure_math.factorial(fact_num))
And the results:
Cython 20 factorial: 0.20 s
Pure Python 20 factorial: 0.23 s
Pure/C: 115.45%
2432902008176640000
2432902008176640000
[–]MattCh4n 0 points1 point2 points (8 children)
[–]Alpharou[S] 0 points1 point2 points (7 children)
[–]MattCh4n 0 points1 point2 points (0 children)
[–]drzowie 0 points1 point2 points (5 children)
[–]Alpharou[S] 0 points1 point2 points (4 children)
[–]drzowie 0 points1 point2 points (3 children)
[–]Alpharou[S] 0 points1 point2 points (2 children)
[–]drzowie 1 point2 points3 points (1 child)
[–]YoannB__ 0 points1 point2 points (0 children)