import ctypes import timeit from typing import Callable # to run this compiled with mypyc # first do: # $ mypyc bench_callback_v2.py # then do: # $ python -m "import bench_callback_v2" # to run this vanilla, just use: # $ python bench_callback_v2.py proto = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int) def f(a: int, b: int, c: int, d:int ) -> int: return 0 _f: Callable[[int, int, int, int], int] = proto(f) c_source = """ #include void bench(int (*f2)(int, int, int, int)) { uint32_t i; for(i = 0; i < 0x4fffff; ++i) { f2(1,2,3,4); } } """ import subprocess subprocess.run(["cc", "-shared", "-fpic", "-o", "libtest.so", "-x", "c", "-"], input=c_source.encode("utf-8")) libtest = ctypes.CDLL("./libtest.so") bench_proto = ctypes.CFUNCTYPE(None, proto) bench = bench_proto(("bench", libtest)) print(timeit.timeit(stmt='bench(_f)', number=1, globals=dict(bench=bench, _f=_f)))