Marrow and PyArrow implement the same Apache Arrow columnar format. This page covers how they relate and how to exchange data between them — in Python and in Mojo — over the Arrow C Data Interface.
Same data model
Both libraries represent the same Arrow memory layout. An int64 array in Marrow and in PyArrow are bitwise identical in memory.
The comparison harnesses are in the tree (python/marrow/tests/bench_*.py, covering marrow vs PyArrow vs Polars vs DuckDB) but no results are recorded yet, so no speed claim is published here rather than an unverified one.
Reproduce them yourself:
pixi run -e bench bench-engines
Two performance numbers are measured and CI-gated: binary size — see Architecture — and the comptime lane’s speed against the runtime lane — see Comptime vs runtime lane.
Zero-copy C Data Interface
Marrow arrays implement the Arrow C Data Interface protocol (__arrow_c_array__ / __arrow_c_schema__), so they exchange data with PyArrow with zero copies at both the Python and Mojo level.
Python level
import syssys.path.insert(0, "../../python") # the built extensionimport marrow as maimport pyarrow as pa# PyArrow -> marrow, via the __arrow_c_array__ protocolpa_arr = pa.array([1, 2, 3, None, 5])ma_arr = ma.array(pa_arr)print(ma_arr)# marrow -> PyArrow, the same way backround_trip = pa.array(ma_arr)print(round_trip, "|", round_trip.type)