HotPDF poate păstra submulțimi de font TrueType și OpenType pe disc și le poate reutiliza între documente și între rulări de proces, astfel încât un lot care randează zece mii de extrase cu aceleași trei fonturi face submulțimea acelor fonturi o dată în loc de zece mii de ori. Cache-ul se configurează cu două proprietăți, se inspectează cu o înregistrare, iar este sigur să-l lăsați pornit: un eșec de cache revine la submulțimea normală în memorie și nu oprește niciodată producerea unui document
Submulțimea este scumpă dintr-un motiv. Construirea unei submulțimi înseamnă parcurgerea închiderii glifelor, rescrierea loca și glyf, reconstruirea cmap și hmtx, și emiterea unei mapări CID pe care o poate adresa PDF-ul. Pentru un document acel cost dispare în zgomot. Pentru un server de rapoarte care produce documente într-o buclă, este adesea cel mai mare bloc individual de timp CPU din rulare
Ce face posibil un hit de cache
Patru lucruri trebuie să corespundă: conținutul fontului, setul de glife folosite, modul de submulțime și schema cache-ului. Ratați oricare dintre ele și HotPDF face submulțimea de la zero, deoarece o submulțime este reutilizabilă doar când ar fi fost oricum identică octet cu octet
Setul de glife este condiția care îi surprinde pe oameni. Două facturi care diferă printr-un singur nume de client folosesc seturi de glife diferite, prin urmare produc submulțimi diferite și intrări de cache diferite. Cache-ul se plătește când documentele partajează un repertoriu de glife — extrase dintr-un șablon fix, formulare ale căror date variabile sunt numerice, cataloage desenate dintr-o singură bază de date de produse — și nu plătește nimic când fiecare document desenează o felie diferită dintr-un font CJK mare. Măsurați înainte de a presupune în ce caz sunteți
var
Pdf: THotPDF;
Info: THPDFFontSubsetCacheInfo;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.EnableFontSubsetting := True;
Pdf.FontSubsetCacheFolder := 'C:\ProgramData\Reports\fontcache';
Pdf.FontSubsetCacheMaxBytes := 64 * 1024 * 1024; // 64 MiB, default is 256
// ... generate the batch ...
Info := Pdf.GetFontSubsetCacheInfo;
LogFmt('subset cache: %d hits, %d misses, %d bytes in %d files',
[Info.HitCount, Info.MissCount, Info.CurrentBytes, Info.FileCount]);
finally
Pdf.Free;
end;
end;
Cum știți că cache-ul face ceva?
GetFontSubsetCacheInfo returnează nouă contoare, iar raportul dintre primele două răspunde direct la întrebare. HitCount și MissCount dau rata de hit. WriteCount și EvictionCount arată dacă intrările supraviețuiesc suficient pentru a fi refolosite sau sunt împinse afară de un buget prea mic. CurrentBytes și FileCount raportează ce este pe disc acum
Ultimele trei sunt cele pentru care merită să dați alerte. CorruptCount numără intrările care au eșuat validarea și au fost eliminate — câteva după o oprire incorectă sunt normale, un flux constant înseamnă că stocarea nu este fiabilă. RejectedCount numără intrările refuzate înainte de folosire. WriteFailureCount numără intrările care nu au putut fi scrise deloc, ceea ce înseamnă de obicei o problemă de permisiuni pe dosar mai degrabă decât ceva legat de fonturi. Niciuna dintre aceste trei nu oprește generarea documentului, exact motivul pentru care trebuie să vă uitați la ele: un cache care nu scrie niciodată tăcut arată la fel din exterior ca un cache care funcționează, cu excepția facturii de CPU
Evacuarea, bugetele și momentul în care reduceți unul
FontSubsetCacheMaxBytes este implicit 268435456 octeți, adică 256 MiB, iar poate fi redus la runtime. Reducerea declanșează evacuarea imediată least-recently-used în loc să aștepte următoarea scriere, astfel încât un serviciu care reacționează la presiunea pe disc poate elibera spațiu în momentul în care decide, nu la un moment ulterior pe care nu îl controlează
Setarea FontSubsetCacheFolder la un șir vid dezactivează nivelul de disc fără a șterge nimic deja stocat, iar fără a schimba un singur octet al ieșirii de font. Aceasta este proprietatea la care să apelați când vreți să izolați cache-ul în timpul depanării: opriți-l, rulați același lot, iar comparați PDF-urile produse. Ar trebui să fie identice, deoarece cache-ul stochează un rezultat, nu o politică
Ce face cache-ul când o intrare este deteriorată
O elimină și face submulțimea normal. Intrările malformate sau trunchiate sunt refuzate înainte ca submulțimea să poată ajunge într-un flux PDF, partea designului care contează cel mai mult: o intrare de cache coruptă care ar fi ajuns într-un document ar produce un PDF cu un program de font rupt, iar acel eșec ar apărea departe de cauza sa — într-un vizualizator, pe mașina unui client, săptămâni mai târziu
Scrierile sunt atomice, astfel încât un cititor nu observă niciodată o intrare scrisă pe jumătate, iar un crash în mijlocul scrierii lasă cache-ul consistent în loc de otrăvit. Intrările de submulțime compacte păstrează datele de remapare CID pe care le cer dicționarele de font PDF/A, astfel încât o submulțime din cache este încă o submulțime conformă — ieșirea de arhivare nu trebuie să ocolească cache-ul pentru a rămâne validă
// Reset the disk tier after a font upgrade or a schema change
Pdf.ClearFontSubsetCache;
// Or move it somewhere writable and let the budget apply immediately
Pdf.SetFontSubsetCacheFolder('D:\cache\fonts');
Unde să puneți dosarul într-o implementare reală
Trei proprietăți decid asta: dosarul trebuie să fie inscriptibil de contul sub care rulează serviciul, ar trebui să stea pe stocare locală mai degrabă decât pe o partajare de rețea, și nu ar trebui să fie în interiorul unui director pe care un pas de implementare îl șterge. Un cache pe o partajare transformă fiecare miss într-un drum dus-întors și fiecare hit în două; un cache sub un dosar de aplicație pe care installerul îl recreează este un cache care pornește rece după fiecare actualizare
Pentru servicii multi-instancia, dați fiecărei instanțe propriul dosar, cu excepția cazului în care ați confirmat că stocarea gestionează înlocuirea atomică concurentă așa cum vă așteptați. Costul unei intrări duplicate este o trecere suplimentară de submulțime; costul depanării unei curse de cache partajat este o după-amiază
Când să apelați la altceva
Cache-ul reduce munca repetitivă. Nu reduce munca primului document, iar nu ajută o sarcină ale cărei seturi de glife nu se repetă niciodată. Dacă ieșirea dumneavoastră este dominată de un font CJK enorm folosit pe text imprevizibil, pârghia mai eficientă este închiderea submulțimii în sine — ce glife sunt atrase, și de ce — acoperită în notele despre închiderea submulțimii de font și formarea glifelor. Dacă lotul dumneavoastră este lent din motive care se dovedesc a nu fi deloc fonturi, prezentarea detaliată despre ieșirea de rapoarte cu fonturi și imagini arată unde se duce de obicei celălalt timp, iar studiul de caz despre bug-ul de ordonare a submulțimii de font din EndDoc este o memento că corectitudinea submulțimii și viteza submulțimii sunt probleme separate
HotPDF este o componentă VCL PDF nativă pentru Delphi și C++Builder, iar cache-ul de submulțimi face parte din bibliotecă mai degrabă decât un serviciu suplimentar, astfel încât un server de rapoarte îl obține setând o singură cale de dosar — vedeți pagina componentei HotPDF pentru lista completă de funcții de font și performanță