Műszaki cikk

Betűtípus-részbetűkészletek gyorsítótárazása lemezen HotPDF-szel Delphiben

A HotPDF képes a TrueType és OpenType betűtípus-részbetűkészleteket lemezen tartani és újrahasználni dokumentumok és folyamatfuttatások között, így egy olyan köteg, amely tízezer kivonatot renderel ugyanazzal a három betűtípussal, ezeket a betűtípusokat egyszer részbetűkészíti ahelyett, hogy tízezerszer. A gyorsítótár két tulajdonsággal konfigurálható, egy rekorddal vizsgálható, és nyugodtan bekapcsolva hagyható: egy gyorsítótár-hiba a normál memóriabeli részbetűkészítésre esik vissza, és sosem állítja meg egy dokumentum előállítását

A részbetűkészítés drága, okból. Egy részbetűkészlet felépítése a glyph-lezárat bejárását, a loca és glyf újraírását, a cmap és hmtx újraépítését, és egy olyan CID-leképezés kibocsátását jelenti, amelyet a PDF megcímezhet. Egy dokumentumnál ez a költség eltűnik a zajban. Egy jelentéskészítő szervernél, amely dokumentumokat állít elő egy ciklusban, gyakran a futás legnagyobb egyetlen CPU-időblokkja

Mi teszi lehetővé egy gyorsítótár-találatot

Négy dolognak kell egyeznie: a betűtípus tartalma, a felhasznált glyphek halmaza, a részbetűkészlet-mód és a gyorsítótár-séma. Bármelyik hiánya esetén a HotPDF a nulláról részbetűkészít, mert egy részbetűkészlet csak akkor újrahasználható, ha egyébként is bájtonként azonos lett volna

A glyph-halmaz az a feltétel, amely meglepi az embereket. Két számla, amelyek egyetlen ügyfélnévben térnek el, különböző glyph-halmazokat használ, és ezért különböző részbetűkészleteket és különböző gyorsítótár-bejegyzéseket állít elő. A gyorsítótár akkor fizeti ki magát, amikor a dokumentumok osztják a glyph-repertoárt — kivonatok fix sablonból, olyan űrlapok, amelyek változó adata numerikus, egy termékadatbázisból rajzolt katalógusok —, és semmit nem fizet, amikor minden dokumentum egy nagy CJK betűtípus más szeletét rajzolja. Mérjük, mielőtt feltételezzük, melyik esetben vagyunk

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;

Honnan tudjuk, hogy a gyorsítótár egyáltalán csinál valamit?

A GetFontSubsetCacheInfo kilenc számlálót ad vissza, és az első kettő aránya közvetlenül megválaszolja a kérdést. A HitCount és MissCount adja meg a találati arányt. A WriteCount és EvictionCount megmutatja, elég sokáig túlélnek-e a bejegyzések az újrahasználathoz, vagy egy túl kis költségvetés kiszorítja-e őket. A CurrentBytes és FileCount azt jelenti, ami épp a lemezen van

A maradék három az, amelyeken érdemes riasztani. A CorruptCount azokat a bejegyzéseket számolja, amelyek megbuktak az ellenőrzésen és el lettek távolítva — néhány egy tiszta leállítás után normális, egy folyamatos adatfolyam azt jelenti, hogy a tároló megbízhatatlan. A RejectedCount a használat előtt visszautasított bejegyzéseket számolja. A WriteFailureCount azokat a bejegyzéseket számolja, amelyeket egyáltalán nem sikerült kiírni, ami általában a mappa jogosultsági problémáját jelenti, nem pedig olyasmit, ami a betűtípusokkal kapcsolatos. Egyik sem állítja le a dokumentumgenerálást, ami éppen az oka annak, hogy nekünk kell megnéznünk őket: egy olyan gyorsítótár, amely csendben sosem ír, kívülről ugyanúgy néz ki, mint egy működő gyorsítótár, a CPU-számla kivételével

Kizárás, költségvetések és az a pillanat, amikor csökkentjük valamelyiket

A FontSubsetCacheMaxBytes alapértelmezett értéke 268435456 bájt, azaz 256 MiB, és futásidőben csökkenthető. A csökkentése azonnali legutóbb-használt kizárást vált ki, ahelyett hogy a következő írásra várna, így egy olyan szolgáltatás, amely lemeznyomásra reagál, abban a pillanatban szabadíthat fel teret, amikor úgy dönt, nem egy olyan későbbi ponton, amelyet nem szabályoz

A FontSubsetCacheFolder üres karakterláncra állítása letiltja a lemezi szintet anélkül, hogy bármit is kiürítene a már tároltakból, és egyetlen bájtnyi betűkimenetet sem változtat. Ez az a tulajdonság, amelyhez nyúljunk, amikor elszigetelni akarjuk a gyorsítótárat hibakeresés közben: kapcsoljuk ki, futtassuk ugyanazt a köteget, és hasonlítsuk össze az előállított PDF-eket. Azonosnak kell lenniük, mert a gyorsítótár egy eredményt tárol, nem házirendet

Mit tesz a gyorsítótár, amikor egy bejegyzés sérült

Eltávolítja, és normálisan részbetűkészít. A hibásan formázott vagy csonka bejegyzéseket a részbetűkészlet PDF-folyamba jutása előtt utasítják vissza, ami a terv legfontosabb része: egy sérült gyorsítótár-bejegyzés, amely bejutott egy dokumentumba, hibás betűprogrammal rendelkező PDF-et állítana elő, és ez a hiba messze az okától jelentkezne — egy megjelenítőben, egy ügyfél gépén, hetekkel később

Az írások atomiak, így egy olvasó sosem figyel meg félreírt bejegyzést, és egy írás közbeni összeomlás konzisztens gyorsítótárt hagy hátra, nem mérgezettet. A tömör részbetűkészlet-bejegyzések megtartják a CID-újraleképezési adatokat, amelyeket a PDF/A betűtípus-szótárak megkövetelnek, így egy gyorsítótárazott részbetűkészlet továbbra is megfelelő részbetűkészlet — az archív kimenetnek nem kell megkerülnie a gyorsítótárat, hogy érvényes maradjon

// 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');

Hova tegyük a mappát egy valódi telepítésben

Három tulajdonság dönti el: a mappának írhatónak kell lennie a szolgáltatás által futtatott fiók számára, helyi tárolón kell lennie, nem hálózati megosztáson, és nem szabad egy olyan könyvtárban lennie, amelyet egy telepítési lépés kitöröl. Egy megosztáson lévő gyorsítótár minden hiányt oda-vissza úttá, minden találatot kettőssé tesz; egy olyan alkalmazásmappa alatti gyorsítótár, amelyet a telepítő újra létrehoz, olyan gyorsítótár, amely minden frissítés után hidegen indul

Többpéldányos szolgáltatásoknál adjunk minden példánynak saját mappát, hacsak nem megerősítettük, hogy a tároló úgy kezeli az egyidejű atomi cserét, ahogy várjuk. Egy duplikált bejegyzés költsége egy extra részbetűkészítési menet; egy megosztott-gyorsítótár-versenyfeltétel hibakeresésének költsége egy délután

Mikor nyúlj valami máshoz

A gyorsítótár ismétlődő munkát csökkent. Nem csökkenti az első dokumentum munkáját, és nem segít egy olyan munkaterhelésen, amelynek glyph-halmazai sosem ismétlődnek. Ha a kimenetünket egy egyetlen hatalmas, kiszámíthatatlan szövegen át használt CJK betűtípus uralja, a hatékonyabb kar a részbetűkészítés lezárata maga — mely glyphek kerülnek bevonsa, és miért —, amelyet a betűtípus-részbetűkészlet-lezárás és shaping glyphek jegyzetei tárgyalnak. Ha a kötegünk olyan okokból lassú, amelyek kiderülnek, hogy egyáltalán nem a betűtípusok, a jelentéskimenet betűtípusokkal és képekkel átjárása megmutatja, hová megy a többi idő általában, és az EndDoc betűtípus-részbetűkészlet-rendelési hiba esettanulmány emlékeztető, hogy a részbetűkészítés helyessége és a részbetűkészítés sebessége külön problémák

A HotPDF natív VCL PDF komponens Delphihez és C++Builderhez, és a részbetűkészlet-gyorsítótár a könyvtár része, nem kiegészítő szolgáltatás, így egy jelentéskészítő szerver egyetlen mappaútvonal beállításával megkapja — a teljes betű- és teljesítményfunkció-listát a HotPDF komponens oldal tartalmazza