C and Python¶
Python is a very high-level language and rather slow. But it is still possible to write your own fast code and execute it with Python as an interface. We will take a look at ctypes
and CFFI as two ways to include your fast C-function into your python program.
# Create shared lib
!gcc -fPIC -shared pi.c -o libpiapprox.so
ctypes
¶
from ctypes import *
libc = CDLL("libc.so.6") # cdll.msvcrt on Windows
print(libc.time(None))
printf = libc.printf
printf(b"%d bottles of beer\n", 42)
piapprox = CDLL("./libpiapprox.so")
pi_approx = piapprox.pi_approx
pi_approx.restype = c_float
print(pi_approx(5000))
1629705815
3.135999917984009
CFFI¶
from cffi import FFI
ffibuilder = FFI()
ffibuilder.cdef("float pi_approx(int n);")
ffibuilder.set_source("_pi", # name of the output C extension
"""
#include "pi.h"
""",
sources=['pi.c'], # includes pi.c as additional sources
libraries=['m']) # on Unix, link with the math library
if __name__ == "__main__":
ffibuilder.compile(verbose=True)
generating ./_pi.c
the current directory is '/builds/fsvmatheinformatik/advancedpython/friday'
running build_ext
building '_pi' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/usr/local/include/python3.9 -c _pi.c -o ./_pi.o
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/usr/local/include/python3.9 -c pi.c -o ./pi.o
gcc -pthread -shared ./_pi.o ./pi.o -L/usr/local/lib -lm -o ./_pi.cpython-39-x86_64-linux-gnu.so
from _pi.lib import pi_approx
approx = pi_approx(10)
print(approx)
approx = pi_approx(10000)
print(approx)
3.5999999046325684
3.1803998947143555