All books

Professional

Apps About Coach Log in Start reading

Quantitative Finance · Glossary

What is Boundary-crossing cost?

Definition 9.3 Research, Data and Risk Platforms · Chapter 9 — Native Extensions

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.

Two routes across the boundary. pybind11 generates a binding that checks each argument’s type and memory layout and can release the interpreter lock while C++ runs; ctypes loads any library with a C interface and passes what it is told, so the Python wrapper must check. Both hand the kernel a pointer into the same numpy buffer.
Figure 9.1. Two routes across the boundary. pybind11 generates a binding that checks each argument’s type and memory layout and can release the interpreter lock while C++ runs; ctypes loads any library with a C interface and passes what it is told, so the Python wrapper must check. Both hand the kernel a pointer into the same numpy buffer.
The cost of calling a one-step function once per element from a Python loop, a million times: as a Python function, as C++ through pybind11, and as Rust through ctypes. Measured on a laptop (Intel Core Ultra 7 155H) under WSL2, one thread, machine otherwise idle. Data: bench_natext.py.
Figure 9.2. The cost of calling a one-step function once per element from a Python loop, a million times: as a Python function, as C++ through pybind11, and as Rust through ctypes. Measured on a laptop (Intel Core Ultra 7 155H) under WSL2, one thread, machine otherwise idle. Data: bench_natext.py.
Read in context →