Skip to content

WolfXL vs openpyxl Benchmark Run

  • Timestamp UTC: 2026-08-16T09:41:22.769698+00:00
  • Git branch: None
  • Git commit: None
  • Git dirty: None
  • Python: 3.13.9
  • WolfXL: 2.1.0
  • openpyxl: 3.1.5
  • Rounds: 3
Case Engine Rows Cols Median seconds Units/sec Phase medians
write_append_plain openpyxl 10,000 5 0.190021 263,129
write_append_plain wolfxl_append 10,000 5 0.018290 2,733,772
write_append_plain wolfxl_write_rows 10,000 5 0.014542 3,438,346
write_append_mixed openpyxl 10,000 5 0.192134 260,235
write_append_mixed wolfxl_append 10,000 5 0.020681 2,417,629
write_append_wide openpyxl 1,000 50 0.161785 309,053
write_append_wide wolfxl_append 1,000 50 0.013812 3,620,150
write_append_formulas openpyxl 2,000 5 0.039858 250,889
write_append_formulas wolfxl_append 2,000 5 0.005391 1,854,886
write_append_formulas wolfxl_write_rows_fast_formula 2,000 5 0.003991 2,505,533
write_styled_cells openpyxl 2,000 5 0.071640 139,587 populate_cells=0.033632s, save=0.037898s
write_styled_cells wolfxl_cell 2,000 5 0.024934 401,051 populate_cells=0.012875s, save=0.011197s
write_styled_cells wolfxl_write_styled_rows 2,000 5 0.011615 860,993 populate_cells=0.007701s, save=0.003548s
write_multi_sheet_plain openpyxl 1,000 5 0.096936 257,903
write_multi_sheet_plain wolfxl_append 1,000 5 0.009319 2,682,679
write_multi_sheet_plain wolfxl_write_rows_fast_multi_sheet 1,000 5 0.005627 4,442,996
write_cell_by_cell_plain openpyxl 2,000 5 0.041770 239,406 construct_loop=0.007725s, save_flush=0.033760s
write_cell_by_cell_plain wolfxl_cell 2,000 5 0.010500 952,347 construct_loop=0.007299s, save_flush=0.003014s
read_values_plain openpyxl 10,000 5 0.231599 215,891
read_values_plain wolfxl 10,000 5 0.015385 3,249,892
read_only_values_plain openpyxl 10,000 5 0.196547 254,392
read_only_values_plain wolfxl 10,000 5 0.016928 2,953,686
read_values_wide openpyxl 1,000 50 0.183695 272,191
read_values_wide wolfxl 1,000 50 0.014293 3,498,216
read_formula_text openpyxl 2,000 5 0.042949 232,835
read_formula_text wolfxl 2,000 5 0.006712 1,489,813
read_styled_cells openpyxl 2,000 5 0.058847 169,932
read_styled_cells wolfxl 2,000 5 0.016429 608,664
read_multi_sheet_values openpyxl 5,000 5 0.114464 218,410
read_multi_sheet_values wolfxl 5,000 5 0.010505 2,379,734
modify_two_cells_plain openpyxl 10,000 5 0.680720 3 modify_save=0.431743s, setup_copy=0.000403s, verify_load=0.231801s
modify_two_cells_plain wolfxl_modify 10,000 5 0.277661 7 modify_save=0.031171s, setup_copy=0.000393s, verify_load=0.247503s
large_write_append_plain openpyxl 200,000 8 3.747834 426,913
large_write_append_plain wolfxl_append 200,000 8 0.380747 4,202,269
large_write_append_plain wolfxl_write_rows 200,000 8 0.293017 5,460,432
large_read_values_plain openpyxl 200,000 8 4.909174 325,920
large_read_values_plain wolfxl 200,000 8 0.331621 4,824,782
large_read_only_values_plain openpyxl 200,000 8 3.841151 416,542
large_read_only_values_plain wolfxl 200,000 8 0.289890 5,519,337
large_modify_two_cells_plain openpyxl 200,000 8 15.410541 0 modify_save=9.361222s, setup_copy=0.002489s, verify_load=6.046747s
large_modify_two_cells_plain wolfxl_modify 200,000 8 6.808778 0 modify_save=0.598325s, setup_copy=0.002759s, verify_load=6.207687s

Speedup >1.0x means WolfXL is faster (higher is better).

Case WolfXL path Speedup vs openpyxl
large_modify_two_cells_plain wolfxl_modify 2.26x
large_read_only_values_plain wolfxl 13.25x
large_read_values_plain wolfxl 14.80x
large_write_append_plain wolfxl_append 9.84x
large_write_append_plain wolfxl_write_rows 12.79x
modify_two_cells_plain wolfxl_modify 2.45x
read_formula_text wolfxl 6.40x
read_multi_sheet_values wolfxl 10.90x
read_only_values_plain wolfxl 11.61x
read_styled_cells wolfxl 3.58x
read_values_plain wolfxl 15.05x
read_values_wide wolfxl 12.85x
write_append_formulas wolfxl_append 7.39x
write_append_formulas wolfxl_write_rows_fast_formula 9.99x
write_append_mixed wolfxl_append 9.29x
write_append_plain wolfxl_append 10.39x
write_append_plain wolfxl_write_rows 13.07x
write_append_wide wolfxl_append 11.71x
write_cell_by_cell_plain wolfxl_cell 3.98x
write_multi_sheet_plain wolfxl_append 10.40x
write_multi_sheet_plain wolfxl_write_rows_fast_multi_sheet 17.23x
write_styled_cells wolfxl_cell 2.87x
write_styled_cells wolfxl_write_styled_rows 6.17x

Phase speedups

For phased workloads, this separates setup/verification time from the operation being measured. Speedup >1.0x means WolfXL is faster for that phase.

Case WolfXL path Phase openpyxl seconds WolfXL seconds Speedup
large_modify_two_cells_plain wolfxl_modify modify_save 9.361222 0.598325 15.65x
large_modify_two_cells_plain wolfxl_modify setup_copy 0.002489 0.002759 0.90x
large_modify_two_cells_plain wolfxl_modify verify_load 6.046747 6.207687 0.97x
modify_two_cells_plain wolfxl_modify modify_save 0.431743 0.031171 13.85x
modify_two_cells_plain wolfxl_modify setup_copy 0.000403 0.000393 1.02x
modify_two_cells_plain wolfxl_modify verify_load 0.231801 0.247503 0.94x
write_cell_by_cell_plain wolfxl_cell construct_loop 0.007725 0.007299 1.06x
write_cell_by_cell_plain wolfxl_cell save_flush 0.033760 0.003014 11.20x
write_styled_cells wolfxl_cell populate_cells 0.033632 0.012875 2.61x
write_styled_cells wolfxl_cell save 0.037898 0.011197 3.38x
write_styled_cells wolfxl_write_styled_rows populate_cells 0.033632 0.007701 4.37x
write_styled_cells wolfxl_write_styled_rows save 0.037898 0.003548 10.68x

Operation speedups

For benchmarks with setup or verification phases, this table shows the library operation phase used for claim gating. The full end-to-end timing above is still reported.

Case WolfXL path Operation phase openpyxl seconds WolfXL seconds Speedup
large_modify_two_cells_plain wolfxl_modify modify_save 9.361222 0.598325 15.65x
modify_two_cells_plain wolfxl_modify modify_save 0.431743 0.031171 13.85x

Peak memory (RSS)

Peak resident-set size per workload, each measured in its own subprocess (clean ru_maxrss high-water mark). Baseline is the interpreter with both libraries imported.

Case Engine Rows Cols Peak RSS Delta over baseline
write_append_plain openpyxl 10,000 5 68.7 MiB 19.5 MiB
write_append_plain wolfxl 10,000 5 61.6 MiB 12.2 MiB
read_values_plain openpyxl 10,000 5 72.5 MiB 23.0 MiB
read_values_plain wolfxl 10,000 5 60.4 MiB 11.3 MiB
read_only_values_plain openpyxl 10,000 5 51.0 MiB 1.8 MiB
read_only_values_plain wolfxl 10,000 5 52.0 MiB 2.7 MiB
modify_two_cells_plain openpyxl 10,000 5 77.1 MiB 27.9 MiB
modify_two_cells_plain wolfxl 10,000 5 83.0 MiB 33.5 MiB
large_write_append_plain openpyxl 200,000 8 429.2 MiB 380.0 MiB
large_write_append_plain wolfxl 200,000 8 244.5 MiB 195.3 MiB
large_read_values_plain openpyxl 200,000 8 505.6 MiB 456.4 MiB
large_read_values_plain wolfxl 200,000 8 151.5 MiB 102.1 MiB
large_read_only_values_plain openpyxl 200,000 8 68.0 MiB 18.8 MiB
large_read_only_values_plain wolfxl 200,000 8 52.3 MiB 3.1 MiB
large_modify_two_cells_plain openpyxl 200,000 8 592.2 MiB 543.0 MiB
large_modify_two_cells_plain wolfxl 200,000 8 483.0 MiB 433.6 MiB

Ratio <1.0x means WolfXL uses less memory (lower is better). A ratio >1.0x means WolfXL's peak RSS is higher than openpyxl's. Large-sheet WolfXL reads use the streaming path and skip eager worksheet-wide style hydration, so their peak RSS should stay bounded.

Case WolfXL path Peak ratio Workload delta ratio Workload delta diff
large_modify_two_cells_plain wolfxl 0.82x 0.80x n/a
large_read_only_values_plain wolfxl 0.77x 0.16x n/a
large_read_values_plain wolfxl 0.30x 0.22x n/a
large_write_append_plain wolfxl 0.57x 0.51x n/a
modify_two_cells_plain wolfxl 1.08x 1.20x 5.6 MiB
read_only_values_plain wolfxl 1.02x 1.45x 0.8 MiB
read_values_plain wolfxl 0.83x 0.49x n/a
write_append_plain wolfxl 0.90x 0.62x n/a