The boundary-crossing cost of a native call is the fixed work done on each call, independently of the size of its data: finding the function, checking and converting each argument from a Python object, releasing and reacquiring the interpreter lock, converting the result back and handling errors.
ctypes. Measured on a laptop (Intel Core Ultra 7 155H) under WSL2, one thread, machine otherwise idle. Data: bench_natext.py.