Laatst bijgewerkt: 30 sep, 2026

XLSB vs XLSX for Large Data Sets: A Developer’s Performance Guide

XLSB vs XLSX voor grote datasets: Een prestatiegids voor ontwikkelaars

Als je data‑pipelines, backend‑rapportage‑engines of analysetools bouwt die met Microsoft Excel communiceren, ben je waarschijnlijk tegen "the wall." aangelopen.

Een gebruiker uploadt een werkmap van 450.000 rijen. Je server start worker‑threads, het geheugenverbruik stijgt tot gigabytes, garbage collection bevriest de runtime, en je uitvoering loopt time‑out. Je inspecteert de payload: het is een standaard .xlsx‑bestand.

Om dit op te lossen, besteden ontwikkelaars vaak dagen aan het implementeren van chunking, streaming‑parsers of het offloaden van bestanden naar achtergrond‑workers. Toch vereist een van de meest effectieve optimalisaties geen enkele architecturale herontwerp: het wijzigen van de bestandsextensie van .xlsx naar .xlsb.

In deze gids duiken we onder de motorkap van beide formaten, onderzoeken we waarom hun interne architecturen radicaal verschillende prestatiekenmerken opleveren, vergelijken we concrete benchmarks voor Python en .NET, en schetsen we duidelijke regels voor wanneer binaire werkmappen in productie moeten worden ingezet.

1. Onder de motorkap: OpenXML vs. BIFF12

Om te begrijpen waarom de prestaties zo dramatisch uiteenlopen bij grote datasets, moeten we kijken hoe elk formaat records op schijf opslaat.

       ┌────────────────────────┐         ┌────────────────────────┐
       │     sample.xlsx        │         │      sample.xlsb       │
       │ (ZIP Archive Wrapper)  │         │ (ZIP Archive Wrapper)  │
       └───────────┬────────────┘         └───────────┬────────────┘
                   │                                  │
       ┌───────────▼────────────┐         ┌───────────▼────────────┐
       │   sheet1.xml (UTF-8)   │         │    sheet1.bin (BIFF12) │
       │  Verbose ASCII Tags    │         │ Structured Byte Stream │
       │  <c r="A1"><v>42</v>   │         │ [Opcode][Len][Payload] │
       └────────────────────────┘         └────────────────────────┘

Zowel .xlsx- als .xlsb-bestanden zijn gecomprimeerde ZIP-containers die voldoen aan de Open Packaging Conventions (OPC). Als je een van de bestanden hernoemt naar .zip en het uitpakt, zie je een bekende mapstructuur: _rels, docProps en xl/worksheets/.

Het cruciale verschil zit in de map xl/worksheets/:

  • XLSX slaat bladen op als platte XML-tekst (sheet1.xml).
  • XLSB slaat bladen op als propriëtaire binaire streams (sheet1.bin), gecodeerd met Microsoft’s BIFF12 (Binary Interchange File Format 12).

Hoe XLSX gegevens codeert (XML DOM Overhead)

In een XLSX-werkblad wordt elke cel gedeclareerd met expliciete XML-tags:

<row r="1" spans="1:2">
    <c r="A1" t="s">
        <v>142</v>
    </c>
    <c r="B1">
        <v>98234.55</v>
    </c>
</row>

Bij het lezen van deze rij moet je runtime:

  1. Decomprimeer de ruwe deflate-stroom naar tekst.
  2. Tokeniseer en parse tekenreeks‑karakters naar een XML DOM‑ of SAX‑gebeurtenisstroom.
  3. Valideer openings- en sluitings‑tags (<c>, </c>, <v>, </v>).
  4. Los tekenreeks‑opzoekingen op uit een aparte sharedStrings.xml‑tabel.
  5. Parseer de ASCII‑tekst "98234.55" naar een IEEE 754 64‑bit floating‑point‑getal.

Elke enkele cel veroorzaakt CPU‑overhead voor tekenreeks‑parsen, tekenreeks‑allocatie en lexicale analyse. Vermenigvuldig dit over 500.000 rijen en 30 kolommen (15 miljoen cellen), en de CPU besteedt veel meer cycli aan het parseren van syntaxis dan aan het verwerken van domeinwaarden.

Hoe XLSB gegevens codeert (BIFF12 Binary Stream)

BIFF12 gooit tekstserialisatie volledig weg. In plaats van tekenreeks‑markup worden gegevens gerangschikt als een opeenvolgende reeks variabele‑lengte binaire records:

[Record Type: 2 bytes] [Record Length: 4 bytes] [Payload: N bytes]

Een floating‑point‑cel in BIFF12 gebruikt geen tekenreeks‑representaties zoals "98234.55". Deze wordt direct weergegeven:

  • 2 bytes voor de record‑ID (bijv. BrtCellRk of BrtCellReal)
  • 4 bytes voor kolom‑/rij‑indexen
  • 8 bytes die de ruwe, IEEE 754 double-precision byte-structuur bevatten

Wanneer uw parser een XLSB‑bestand leest, slaat hij de lexicale parsing volledig over. Hij leest de record‑header, pakt de 8 ruwe bytes uit de buffer, kopieert ze rechtstreeks naar het geheugen en verplaatst de pointer vooruit. Er zijn geen tags om te valideren, geen string‑naar‑nummer typeconversies, en nul UTF‑8‑decodeer‑overhead voor numerieke gegevens.

2. Kwantitatieve benchmarks: schijf, geheugen en doorvoersnelheid

Om de impact in de praktijk te illustreren, beschouw een gesimuleerde dataset die 750.000 rijen en 25 kolommen bevat (een mix van tijdstempels, zwevende-kommagetallen, gehele getallen en categoriecijfers).

De onderstaande tests evalueren identieke tabelgegevens die zowel als XLSX als XLSB zijn opgeslagen.

Testomgeving

  • CPU: AMD Ryzen 9 5900X (12 kernen, 24 threads)
  • RAM: 64 GB DDR4‑3600
  • Opslag: PCIe 4.0 NVMe SSD
  • Runtime: Python 3.11 (openpyxl, pyxlsb, calamine) & .NET 8 (ExcelDataReader, ClosedXML)

Kernprestatiestatistieken

MetriekXLSX (OpenXML)XLSB (BIFF12)Delta / Verbetering
Bestandsgrootte op schijf128.4 MB68.2 MB~47% kleiner
Opslaan / Serialisatietijd42.6 s14.1 s3,0x sneller
Leestijd (Python DOM-parser)38.2 s8.9 s4,3x sneller
Leestijd (Rust/C Engine)6.4 s1.9 s3,3x sneller
Piekheapallocatie tijdens lezen~1.85 GB~510 MB~72% reductie

Waarom XLSB-bestanden kleiner zijn

Hoewel beide formaten standaard ZIP-compressie gebruiken, comprimeren binaire streams veel efficiënter dan opgeblazen XML-tekst:

  1. Redundante syntaxis wordt geëlimineerd: XML bevat repetitieve tags (<c r="AA1" s="1">) in elk enkel record. Terwijl ZIP-compressie herhaalde strings vermindert, is de ongecomprimeerde datastroom enorm.
  2. Numerieke dichtheid: In XML vereist het getal 12345678.9012 14 bytes ASCII-tekst. In BIFF12 wordt het opgeslagen als een 8-byte double (of verpakt in een 4-byte RK-record als het binnen specifieke precisieregels past).

3. Geheugenvoetafdruk en druk op Garbage Collection

Voor webservices en microservices die gelijktijdige verzoeken afhandelen, is CPU-snelheid slechts de helft van de strijd; geheugengebruik is waar applicaties daadwerkelijk falen.

XLSX Parsing Heap Profile:
[ String Buffer ] -> [ Tokenizer ] -> [ XML DOM Nodes ] -> [ Object Boxing ]
▲ Massive Gen 0/1 heap allocation -> Triggers aggressive Garbage Collection

XLSB Parsing Heap Profile:
[ Byte Buffer ] -> [ Fixed Struct Copy ] -> [ Destination Array ]
▲ Minimal allocations -> Low GC overhead

Wanneer een XML-parser een XLSX-bestand van 100 MB verwerkt, moet hij duizenden tijdelijke string‑tokens, string‑slice‑buffers en woordenboek‑opzoekingen aanmaken. In garbage‑collected talen (Java, C#, Go, Node.js, Python) veroorzaakt dit extreme heap‑fragmentatie en dwingt het de runtime tot frequente Garbage Collection (GC)-pauzes.

Omdat XLSB-parsing direct werkt op byte‑slices met vaste breedte, kunnen parsers gegevens lezen in stack‑gealloceerde structuren of herbruikbare byte‑buffers. Het resultaat is een dramatisch verkleinde geheugen‑voetafdruk en geen thrashing van de runtime‑allocator.

4. Voorbeeldimplementaties voor ontwikkelaars

Laten we bekijken hoe we XLSB kunnen benutten in gangbare ontwikkelaarstoolchains.

Python: Migreren van OpenPyXL naar Calamine / PyXLSB

Standaard gebruikt pandas.read_excel('data.xlsx') openpyxl, wat een zware in‑memory boom opbouwt.

Om grote XLSB‑bestanden met maximale snelheid te verwerken, gebruik je de Rust‑aangedreven calamine‑engine (beschikbaar via python-calamine en geïntegreerd in moderne Pandas):

import pandas as pd
import time

filename_xlsx = "large_dataset.xlsx"
filename_xlsb = "large_dataset.xlsb"

# Reading standard XLSX (uses openpyxl by default)
t0 = time.perf_counter()
df_xlsx = pd.read_excel(filename_xlsx, engine="openpyxl")
print(f"XLSX loaded in {time.perf_counter() - t0:.2f}s")

# Reading XLSB with Calamine (Rust engine)
t0 = time.perf_counter()
df_xlsb = pd.read_excel(filename_xlsb, engine="calamine")
print(f"XLSB loaded in {time.perf_counter() - t0:.2f}s")

Als je enorme datasets rij voor rij doorloopt zonder de volledige matrix in een DataFrame te laden, biedt pyxlsb een lichtgewicht streaming‑iterator:

from pyxlsb import open_workbook

total_sum = 0.0

with open_workbook("massive_export.xlsb") as wb:
    with wb.get_sheet(1) as sheet:
        for row in sheet:
            # Cell 0 contains an RK integer or Double float
            val = row[0].v
            if val is not None:
                total_sum += val

print(f"Aggregated Total: {total_sum}")

C# / .NET: High-Performance Stream Inname

In .NET zijn bibliotheken zoals ClosedXML of EPPlus uitstekend voor standaardgeneratie, maar voor het inlezen van grote bestanden zonder geheugenuitputting is ExcelDataReader met XLSB‑ondersteuning uitzonderlijk snel:

using System;
using System.IO;
using ExcelDataReader;

public class XlsbProcessor
{
    public static void ProcessBinarySheet(string filePath)
    {
        // ExcelDataReader automatically identifies BIFF12 from file headers
        using var stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
        using var reader = ExcelReaderFactory.CreateReader(stream);

        long rowCount = 0;
        double aggregateValue = 0;

        while (reader.Read())
        {
            rowCount++;
            
            // Read column directly without boxing overhead where possible
            if (!reader.IsDBNull(0))
            {
                aggregateValue += reader.GetDouble(0);
            }
        }

        Console.WriteLine($"Processed {rowCount:N0} rows. Sum: {aggregateValue:F2}");
    }
}

5. Architecturale Afwegingen: Wanneer XLSB NIET te gebruiken

Ondanks de overweldigende prestatievoordelen is XLSB geen wondermiddel. Je moet verschillende operationele afwegingen overwegen voordat je het door je hele stack heen afdwingt:

                      DECISION MATRIX
                      
               Is file size > 50MB OR 
               rows > 100,000?
                    │
         ┌──────────┴──────────┐
        YES                    NO
         │                     │
   Do third-party        Use standard XLSX
   tools strictly        (Maximum compatibility)
   require OpenXML?
         │
    ┌────┴────┐
   YES        NO
    │         │
Use XLSX   Use XLSB
(Stream)   (Max speed & efficiency)

1. Ecosysteem- en Bibliotheekondersteuning

  • XLSX: Universeel. Vrijwel elke programmeertaal, bibliotheek, SaaS‑tool (Google Sheets, Airtable, Tableau) en web‑parser ondersteunt OpenXML van nature.
  • XLSB: Minder alomtegenwoordig. Terwijl Excel, LibreOffice en volwassen ontwikkelaarsbibliotheken (ExcelDataReader, pyxlsb, calamine, Aspose) het ondersteunen, hebben veel lichtgewicht pakketten of pure web‑gebaseerde JavaScript‑parsers (zoals oudere versies van SheetJS) beperkte of alleen‑lezen ondersteuning.

2. Git & Versiebeheer Diffing

  • XLSX: Omdat het tekst‑XML bevat binnen een ZIP‑container, kunnen commandoregel‑hulpmiddelen en Git‑hooks het zip‑bestand uitpakken en de XML formatteren om leesbare structurele verschillen tussen commits te genereren.
  • XLSB: Pure binaire data. Versiebeheersystemen behandelen het strikt als een ondoorzichtige binaire blob, waardoor elke mogelijkheid voor gedetailleerde diff’s of regel‑niveau merges wordt geëlimineerd.

3. Webclient-weergave

Als uw architectuur afhankelijk is van het direct weergeven van spreadsheets in de browser via WebAssembly of client‑side JavaScript, zijn XLSX‑parsers aanzienlijk rijper en minder vatbaar voor randgeval‑renderingsbugs dan client‑side binaire parsers.

4. Derde-partij Innamepijplijnen

Als u bestanden exporteert voor externe bedrijfs­klanten, markeren veel strenge bedrijfs­beveiligings­beleid .xlsb‑bestanden. Omdat BIFF12‑bestanden VBA‑macro’s op dezelfde manier kunnen opslaan als .xlsm‑bestanden (zonder een aparte extensie te vereisen), plaatsen sommige e‑mailfilters en firewall‑scanners .xlsb‑uploads in quarantaine als potentiële macro‑bevatende bedreigingen.

6. Samenvattende Vergelijking: Welk Formaat Wint?

FunctieXLSXXLSBWinnaar
Leessnelheid / parse‑snelheidMatig tot slechtRazendsnelXLSB
Schrijf‑ / generatiesnelheidCPU‑intensiefSnelXLSB
BestandscompressieGoedUitstekend (~40-50% kleiner)XLSB
GeheugenallocatieHoog (Zware GC-druk)Laag (Direct byte lezen)XLSB
Interoperabiliteit van toolsUniverseelHoog, maar selectiefXLSX
Wrijving bij beveiligingsscanningMinimaalAf en toe valse positievenXLSX
Macro-mogelijkheidNee (.xlsm vereist)Ja (ondersteunt macro’s native)Gelijkspel

7. Het Oordeel van de Ontwikkelaar

Gebruik XLSX wanneer:

  • Bestanden zijn klein tot middelgroot (< 50.000 rijen).
  • Je bestanden moeten worden ingelezen door SaaS-platformen van derden of consumentenapps (bijv. Google Sheets).
  • Je kunt de omgeving van de eindgebruiker die het bestand leest niet beheersen.

Schakel over naar XLSB wanneer:

  • Je bouwt interne pipelines, batchtaken, ETL-systemen of worker-taken die enorme data-extracties verwerken (> 100.000 rijen).
  • Uw servers krijgen out-of-memory (OOM)-fouten tijdens het serialiseren of deserialiseren van spreadsheets.
  • U moet de opslagvoetafdrukken van S3/blob en de netwerktijd voor grote terugkerende financiële modellen of data‑exports minimaliseren.

De overstap naar XLSB is vaak zo simpel als het wijzigen van een configuratiestring in uw exportservice, maar levert wel de 3‑ tot 5‑voudige doorvoersnelheidstoename op die normaal weken aan code‑optimalisatie vereist.

Veelgestelde vragen (FAQ)

**Q1: Ondersteunt een XLSB-bestand exact dezelfde rij‑ en kolomlimieten als een XLSX-bestand? Ja; zowel XLSB als XLSX delen exact dezelfde rasterlimiet van 1.048.576 rijen bij 16.384 kolommen per werkblad.

**Q2: Kan een XLSB‑bestand veilig VBA‑macro’s opslaan zonder de bestandsextensie te wijzigen? Ja, in tegenstelling tot XLSX (dat moet worden opgeslagen als XLSM om code uit te voeren), ondersteunt XLSB native binaire VBA‑macroopslag binnen hetzelfde .xlsb‑bestandsformaat.

**Q3: Waarom verkleint het opslaan van een bestand als XLSB de bestandsgrootte als beide formaten al ZIP‑gecomprimeerd zijn? XLSB elimineert uitgebreide tekstopmaak‑tags en codeert celposities, records en ruwe numerieke waarden in compacte binaire byte‑streams die veel dichter comprimeren dan gewone XML‑strings.

**Q4: Kan Google Sheets XLSB‑bestanden direct importeren en bewerken? Nee; Google Sheets kan .xlsb‑bestanden niet rechtstreeks openen of converteren, waardoor je ze eerst moet omzetten naar .xlsx of CSV voordat je ze importeert.

**Q5: Zijn XLSB‑bestanden gevoeliger voor gegevenscorruptie dan XLSX‑bestanden? Hoewel XML‑bestanden soms handmatig kunnen worden geïnspecteerd of gerepareerd met een teksteditor bij gedeeltelijke corruptie, vereisen binaire BIFF12‑streams strikte byte‑offsets en zijn ze moeilijk handmatig te herstellen als structurele sectoren beschadigd zijn.

Zie ook