XLSX comparison takes minutes even for identical files; time grows about cubically with cell count

  • Product: GroupDocs.Comparison for Java 26.10
  • Runtime: Zulu OpenJDK 21.0.11, macOS 26.6.2, Apple M4 Pro, 48 GB
  • License: metered and evaluation mode, same timings

Summary

Comparing XLSX files is very slow, even when the two workbooks are identical. Compare time grows roughly with the cube of the number of cells: doubling the cells makes it about 7 times slower. Two identical copies of a plain 200 × 20 grid of short text take 2.5 minutes, and a 300-row × 23-column report takes 3.5 to 12 minutes.

Steps to reproduce

  1. grid-200x20.xlsx has one sheet with a header row and 200 × 20 cells of short text (r12c3). No styles, links or formulas. grid-200x20-copy.xlsx is an identical copy.
  2. Compare them with default options (SlowCompareRepro.java in the attachment):
try (Comparer comparer = new Comparer("grid-200x20.xlsx")) {
  comparer.add("grid-200x20-copy.xlsx");
  comparer.compare("result.xlsx", new CompareOptions());
}

Expected

A few seconds at most for 4,000 short cells, especially with no differences.

Actual

compare() takes 153.8 s and reports 0 changes. Opening the files and add() take under 100 ms.

Timings

Identical files, compare() only, 0 changes in every run. Plain grids made with Grid.java (attached):

Rows × columns Cells Compare time
1000 × 1 1,000 2.8 s
100 × 5 500 1.8 s
200 × 5 1,000 8.0 s
400 × 5 2,000 58.7 s
100 × 20 2,000 22.5 s
200 × 20 4,000 153.8 s

A synthetic report shaped like our real documents, sbom-shaped-300.xlsx (300 rows × 23 columns, about 3,200 non-empty cells, 563 hyperlinks, some multi-line cells), takes 705.9 s (11 min 46 s) compared with itself. A real report of the same shape, which we can’t share, takes 203.9 s.

We varied the synthetic report to see what drives the time. Hyperlinks, wrapped text, extra sheets and long text make little difference. The number of cells does: at 50 rows it takes 5.5 s, at 100 rows 31 s, and at 300 rows 706 s.

Impact

We run one comparison per job in a container, so every Excel job takes minutes of CPU. Generated release documents (SBOM, risk tables, traceability matrices) routinely have hundreds of rows and 20+ columns.

Question

Is this expected for spreadsheet comparison, and is there an option that avoids it, for example skipping unchanged rows or limiting how far rows are searched for a match? If not, could the cell comparison be made to scale closer to linearly?

Related: XLSX comparison matches rows by position, so one deleted row marks every following row as changed

Attachment

groupdocs-xlsx-speed-repro.zip: grid-200x20.xlsx, grid-200x20-copy.xlsx, sbom-shaped-300.xlsx, SlowCompareRepro.java, Grid.java (generates grids of other sizes, needs Apache POI), timings.txt

groupdocs-xlsx-speed-repro.zip (18.2 KB)