Tehnički članak

Skladište ćelija po blokovima redova i strujna XLSX snimanja u HotXLS

HotXLS čuva ćelije radnog lista u kompaktnim blokovima od 256 redova, razrešava formatiranje reda, kolone i pravougaonika kroz lenje intervalne prelive umesto kreiranja objekata ćelija, i struji svaki red direktno u deflate tok paketa pri snimanju. Zajedno te tri promene odlučuju profil memorije velike radne sveske: vršna upotreba prati najveći pojedinačni red a ne veličinu kompletnog XML-a radnog lista

Razlog zašto je to važno jeste oblik koji svaki programer proračunskih tablica na kraju sretne. Korisnik formatira celu kolonu — jedan klik, milion ćelija — a naivan model objekata odgovara alociranjem milion objekata ćelija da drži jedan indeks formata broja. Fajl na disku ostaje malen jer XLSX format izražava to kao jedan <col> unos. Proces uopšte ne ostaje malen

Zašto formatiranje kolone košta više memorije nego njeno popunjavanje?

Zato što formatiranje nema podatke da opravdaju objekat. Ćelija sa vrednošću mora postojati negde. Ćelija koja je prazna ali stilizovana postoji samo da nosi indeks stila, a materijalizacija miliona takvih jeste klasičan način na koji Delphi aplikacija za proračunske tablice ostane bez adresnog prostora na fajlu koji Excel otvara istog trenutka

Intervalni prelazi stilova uklanjaju potrebu. Instrukcija formatiranja reda, kolone ili pravougaonika se čuva jednom kao opseg plus delovi stila koje doprinosi, i razrešava se lenjo kad se ćelija u tom opsegu stvarno pristupi. Prelivi preživljavaju strukturne izmene — umetanje reda unutar formatiranog bloka pomiče interval umesto da ga ponovo izgradi — i idu povratnim putem kao kompaktne kolone, redovi i unosi ćelija samo sa stilom, što je tačno kako ih Excel piše

Dijagram preklapanja stila intervala za HotXLS koji pokazuje opseg formatiranja kolone sačuvan kao jedan zapis sa pripojenim delovima formata umesto milion praznih objekata ćelija u Delphi-ju
Format kolone, reda ili pravougaonika živi jednom kao zapis preklapanja intervala polažući pravo samo na delove koje poseduje. Efektivni stil sastavlja se lenjo prvi put kad se ćelija unutar opsega zaista dotakne
var
  Sheet: TXLSXWorksheet;
  State: TXLSXCellStyleState;
begin
  Sheet := Workbook.Sheets[1];
  // Indeksi stila potiču iz baze stilova radne sveske, npr. iz ćelije
  // koju ste već formatirali onako kako želite da opseg izgleda
  State := BuildStateFromTemplateCell(Sheet.Cells.Item[1, 1]);
  // Formatiranje kolona B..D bez pravljenja ijednog praznog objekta ćelije
  Sheet.StyleOverlays.Add(1, 2, MaxRowIndex, 4,
    [xfpNumberFormat, xfpAlignment], State);
end;

TXLSXFormatParts jeste skup koji odlučuje šta preliv doprinosi: xfpFont, xfpFill, xfpBorder, xfpNumberFormat, xfpAlignment i xfpProtection. Imenovanje samo delova koje mislite jeste ono što omogućava prelivima da se slažu razumno — preliv kolone koji isporučuje format broja se ne bori sa prelivom reda koji isporučuje ispunu, jer nijedan ne polaže pravo na deo drugog

Šta vam daje blok od 256 redova

Lokalnost. Ćelije se drže u blokovima od 256 redova sa stabilnim javnim ručicama, serijalizovano po redovima, tako da pisanje radnog lista obilazi memoriju redom kojim će emitovati bajtove a ne goneći pokazivače po gomili. Stabilne ručice su važne za API površinu: ručica koju pozivalac drži ostaje validna kroz internu reorganizaciju koju raspored blokova izvodi, što je ono što čini kompaktnu reprezentaciju detaljom implementacije a ne prelomnom promenom

Dijagram skladištenja blokova redova koji pokazuje HotXLS ćelije radnog lista držane u fiksnim blokovima od 256 redova sa stabilnim Delphi handle-ovima i serializacijom red-po-glavnom u XLSX deflate tok
Ćelije sede u fiksnim blokovima od 256 redova koji alociraju samo zauzete redove i serializuju se istim redom kojim bajtovi napuštaju proces. Javni handle-ovi prežive unutrašnju reorganizaciju, pa raspored blokova ostaje nevidljiv pozivaocima

Kompakcija bazena stilova radi uz to. Pre svakog snimanja, fontovi, ispune, ivice, formati brojeva, poravnanja i zaštite koje nijedna ćelija ne referencira se odbacuju. Dugovečne radne sveske akumuliraju nereferencirane zapise stilova onako kako dugovečni dokumenti akumuliraju nekorišćene stilove, a radna sveska koju je korisnik uređivao sat vremena može nositi stotine njih u fajlu iz kojeg ih niko nikada neće pročitati

Snimanje strujanjem po redovima, i kad se ne primenjuje

Sa StreamingWrite omogućenim — podrazumevano — svaki red radnog lista se piše direktno u deflate tok paketa. Alternativa, koju zastavica isključuje, gradi kompletan XML radnog lista prvo i kompresuje ga naknadno, tako da vršna memorija skače sa celim listom. Strujanje čini da skače sa jednim redom

Deljeni nizovi i pomoćni delovi prate istu disciplinu kroz jedan ponovo upotrebljiv UTF-8 serijalizator koji emituje unose jedan po jedan, ograničavajući vršnu memoriju po najvećem pojedinačnom unosu a ne po celom delu. To pokriva tabelu deljenih nizova i pivot zapise, koji na širokoj analitičkoj radnoj svesci često jesu veći od bilo kog pojedinačnog radnog lista

var
  Workbook: TXLSXWorkbook;
begin
  Workbook := TXLSXWorkbook.Create;
  try
    Workbook.Open('ledger-2026.xlsx');
    // StreamingWrite je podrazumevano True; isključite ga samo kada nizvodni
    // korak zahteva da čitav XML radnog lista postoji pre kompresije
    Workbook.StreamingWrite := True;
    Workbook.SaveAs('ledger-2026-out.xlsx');
  finally
    Workbook.Free;
  end;
end;

Ostavite ga uključenim osim ako nemate konkretan razlog da ne. Nestrujna putanja postoji za slučajeve kad nešto drugo u liniji obrade treba sastavljeni XML, a plaćanje za to podrazumevano jeste plaćanje za slučaj koji većina aplikacija nikad ne pogodi

Kako da znate da li se preliv zaista koristi

Gledajte broj ćelija, a ne graf memorije. Ako radni list prijavljuje uverljiv broj fizičkih ćelija nakon što ste primenili široko formatiranje, preliv radi svoj posao. Ako broj skoči za veličinu formatiranog opsega, nešto u putanji koda materijalizovalo je ćelije — obično petlja koja čita svaku ćeliju u opsegu da proveri njen stil, što prisiljava razrešenje po jednoj ćeliji u isto vreme i pobeđuje čitav raspored

StreamingWrite dijagram koji poredi deflate strujanje po redu u HotXLS sa sklapanjem celog XML-a radnog lista u memoriji pre kompresije u Delphi-ju
Sa StreamingWrite uključenim, svaki red struji ravno u deflate tok paketa i vršna memorija prati jedan red. Isključenje zastavice prvo sastavlja ceo XML radnog lista, što skalira vršnu memoriju s celim listom

Razrešite stil kad vam treba efektivni format jedne ćelije. Ne razrešujte stil za milion ćelija da biste saznali da kolona ima format broja; pitajte preliv. Isto pravilo važi za pisanje: dodelite vrednosti ćelijama koje imaju vrednosti, a formatiranje neka ostane interval

Gde odlazi preostala memorija

Kad su ćelije i stilovi kompaktni, sledeći najveći potrošači na velikoj radnoj svesci jesu tabela deljenih nizova i satelitski delovi koje fajl nosi — pivot keševi, crteži, očuvani XML iz delova koje model objekata ne modeluje. Ti imaju svoje strategije, i iskren odgovor je da nijedno pojedinačno podešavanje ne rešava sve odjednom

Ako je usko grlo otvaranje a ne snimanje, selektivno učitavanje je poluga: prolaz kroz učitavanje radnih listova samo sa metapodacima i selektivno pokriva čitanje radne sveske bez plaćanja za listove koje nećete dirati. Za propusnost putanje čitanja na veoma velikim fajlovima, pogledajte beleške o paralelnom XLSX parsiranju i alokatoru memorije, a za opterećenja samo za izlaz kojima model objekata uopšte ne treba, strujna upisivanja za paketne poslove servera su obično bolje uklapanje nego bilo kakvo štelovanje ovde

HotXLS čita i piše XLS i XLSX iz nativnog Delphi i C++Builder koda bez instalacije Excel-a i bez OLE automatizacije, što je ono što čini ove karakteristike memorije uočljivim i upravljivim u prvi mah — stranica HotXLS Delphi komponente za proračunske tabele navodi podržane formate i verzije RAD Studio-a