The performance record

The time and peak memory of reading and writing synthetic data at a fixed width of 100 columns and 10,000 rows / 100,000 rows (1,000,000 cells / 10,000,000 cells) — the standard of Appendix B.39.11. These numbers are not remembered but measured by scripts/bench.sh; the numbers the README quotes are those of the 10,000-row tier, and they are checked by machine against this page's source. A cell that could not be measured says why — an operation this machine's physical memory or free disk cannot hold is decided against, and recorded, before it can fall over.

Measurement 10,000 rows (1,000,000 cells) 100,000 rows (10,000,000 cells)
What was doneTimePeak memoryTimePeak memory
Build the model
put every cell into a Workbook (no file)
0.37 s203.1 MB 3.85 s1079.2 MB
Write (xlsx)
model -> .xlsx
0.93 s214.8 MB
of which the model: 202.8 MB
10.02 s1168.3 MB
of which the model: 1168.3 MB
Read (xlsx)
.xlsx -> model, then sum every cell
1.47 s213.3 MB 15.37 s1054.4 MB
Streaming read (xlsx)
StreamingReader, row by row, then sum every cell
1.01 s13.2 MB 10.16 s19.7 MB
Open, change one cell, save
.xlsx -> model -> .xlsx
2.20 s209.1 MB 23.17 s1080.5 MB
Format detection
SheetFormat.detect(contentsOf:), per call
under 1 ms7.0 MB under 1 ms7.0 MB
Inspect before reading
Workbook.inspect(contentsOf:)
2.0 ms10.6 MB 3.0 ms10.6 MB
Streaming write (xlsx)
StreamingWriter, row by row
1.10 s10.8 MB 11.35 s10.8 MB
Streaming read (xlsx) (the streaming writer's file)
StreamingReader, row by row, then sum every cell
1.08 s12.8 MB 10.84 s12.8 MB
Format detection (the streaming writer's file)
SheetFormat.detect(contentsOf:), per call
under 1 ms7.0 MB under 1 ms7.0 MB
Inspect before reading (the streaming writer's file)
Workbook.inspect(contentsOf:)
2.0 ms10.6 MB 2.0 ms10.6 MB
Write (xlsx, 8 sheets)
the same cells split across 8 sheets, model -> .xlsx
0.85 s207.5 MB
of which the model: 196.6 MB
9.90 s1293.2 MB
of which the model: 1098.2 MB
Read (xlsx, 8 sheets, one at a time)
ReadOptions(concurrency: 1), then sum every cell
1.35 s139.1 MB 14.63 s1045.1 MB
Read (xlsx, 8 sheets, side by side)
the default (sheets read concurrently), then sum every cell
0.65 s228.8 MB 6.99 s1222.2 MB
Write (ods)
model -> .ods
1.81 s213.2 MB
of which the model: 202.9 MB
18.99 s1209.3 MB
of which the model: 1209.3 MB
Read (ods)
.ods -> model
2.46 s208.0 MB 25.07 s1230.5 MB
Streaming read (ods)
StreamingReader, row by row, then sum every cell
2.42 s14.5 MB 24.35 s14.5 MB
Streaming write (ods)
StreamingWriter, row by row
1.64 s21.6 MB 16.36 s16.7 MB
Streaming read (ods) (the streaming writer's file)
StreamingReader, row by row, then sum every cell
2.42 s14.5 MB 24.03 s14.5 MB
Write (csv)
model -> .csv
0.48 s237.6 MB
of which the model: 202.9 MB
5.60 s1290.5 MB
of which the model: 1215.4 MB
Read (csv)
.csv -> model (with type inference)
0.79 s165.3 MB 8.65 s1293.2 MB
Streaming read (csv)
CSVStreamingReader, row by row
0.50 s10.8 MB 5.08 s11.0 MB
Streaming write (csv)
CSVStreamingWriter, row by row
0.48 s7.7 MB 4.86 s7.7 MB
Streaming read (csv) (the streaming writer's file)
CSVStreamingReader, row by row
0.50 s10.8 MB 5.09 s11.0 MB
Write (numbers)
model -> .numbers
2.03 s374.0 MB
of which the model: 202.8 MB
21.37 s1372.1 MB
of which the model: 1104.0 MB
Read (numbers)
.numbers -> model, then sum every cell
1.01 s279.2 MB 10.63 s1759.4 MB
Streaming read (numbers)
StreamingReader, row by row, then sum every cell
0.51 s24.8 MB 4.53 s59.6 MB
Streaming write (numbers)
StreamingWriter, row by row
2.93 s25.5 MB 26.84 s65.7 MB
Streaming read (numbers) (the streaming writer's file)
StreamingReader, row by row, then sum every cell
0.50 s24.8 MB 4.49 s59.6 MB

Conditions of measurement

Measuring on your own machine

scripts/bench.sh                # both tiers: rebuilds Benchmarks/ in release, measures, writes docs/performance.json
scripts/bench.sh --rows 10000   # one tier only
python3 scripts/build-performance-page.py --check   # this page and the README's numbers match the source