0

I wrote a simple factorial function and tested its performance. But surprisingly my function is faster than math.factorial. Why it might happen? Am I doing everything correct?

Changing the return and argument data type to long long, also fast.

Cpp code:

#include "fact.hpp"


int fact(int n) {
  if (n<=1) {
    return 1;
  }
  return n*fact(n-1);
} 

My test python script is given bellow. Cpp binding is done using Cython.

import cython_fact
import timeit

setup1 = """
def fact(n):
    s = 1
    for i in range(1, n+1):
        s*=i
    return s
"""
code1 = """
fact(50)  
"""

setup2 = """
from cython_fact import factorial 
"""
code2 = """
factorial(50) 
"""

setup3 = """
from math import factorial
"""
code3 = """
factorial(50) 
"""

print(timeit.timeit(stmt=code1, setup=setup1))
print(timeit.timeit(stmt=code2, setup=setup2))
print(timeit.timeit(stmt=code3, setup=setup3))

Outputs:

1.555461709
0.01813229099999991
0.20942320800000003

EDIT: Had some silly mistake in factorial calculation.

  • 1
    2! = 2, not 1 as in your c implementation – Ruggero Turra Apr 20 '23 at 07:31
  • 5
    Ignoring the fact that your function doesn't give the correct results, feel free to compare the result for something like n = 20. Your C function will overflow, math.factorial won't. Simply put, taking care of this takes time and therefore math.factorial is slightly slower. – joni Apr 20 '23 at 07:38
  • @joni Your point actually makes sense. I think that might be the actual reason. – Assan Kozhin Apr 20 '23 at 07:45

1 Answers1

0

Actually the performance difference between C and Python execution is not surprising at all. C is compiled into machine code and does not need an interpreter or virtual machine. Python needs an interpreter to execute. And Java for example needs a virtual machine.

Using the Cython extension, it's C code inside Python will be compiled once and can be done with all major C compilers.

Read this article to understand the difference of a virtual machines, interpreters and compilers: Difference between compiled and interpreted languages?

The interpreter is the reason for a slower performance, because C is already compiled using a C compiler directly to machine code: "All of this makes Cython the ideal language for wrapping external C libraries, embedding CPython into existing applications, and for fast C modules that speed up the execution of Python code."

kenneth
  • 478
  • 4
  • 11