These figures are the project’s own, measured on Python 3.13.1, AMD Ryzen 9 7900X, 24 CPUs, 64 GB RAM, with 15 repetitions per measurement, each isolated in a subprocess with peak-RSS tracking. Your hardware will differ.
One million rows
Versions under test: Jetxl 0.3.0, Polars 1.42.1, PyArrow 24.0.0, Pandas 3.0.3, PyExcelerate 0.13.0, rustpy-xlsxwriter 0.5.2, openpyxl 3.1.5, XlsxWriter 3.2.9.
Across sizes
Memory
Worth separating from speed, because the ranking differs. Jetxl uses 958 MB at a million rows, whilepolars.write_excel uses 3.13 GB and pandas + openpyxl uses 2.95 GB. But rustpy_xlsxwriter uses 238 MB, four times less than Jetxl, while being 6.5 times slower. If memory is tighter than time, that trade may favor it.
Where the speed comes from
Zero-copy Arrow access
Zero-copy Arrow access
Jetxl reads values from DataFrame buffers in place, with no intermediate Python objects.
SIMD XML escaping
SIMD XML escaping
Hardware-accelerated string processing for the escaping every cell requires.
Pre-calculated buffers
Pre-calculated buffers
Output size is computed up front, so each sheet allocates once instead of growing repeatedly.
Parallel sheet generation
Parallel sheet generation
Multi-sheet XML is produced across threads.
Streaming compression
Streaming compression
ZIP compression happens on the fly rather than over a finished buffer.