Teknik Makale

Delphi'de HotPDF ile Yazı Tipi Alt Kümelerini Diskte Önbelleğe Alma

HotPDF, TrueType ve OpenType yazı tipi alt kümelerini diskte tutabilir ve onları belgeler ve süreç çalıştırmaları arasında yeniden kullanabilir, dolayısıyla aynı üç yazı tipiyle on bin ekstre işleyen bir toplu iş o üç yazı tipini on bin kez yerine bir kez alt kümeler. Önbellek iki özellikle yapılandırılır, tek bir kayıtla incelenir ve açık bırakılması güvenlidir: bir önbellek hatası normal bellek içi alt kümeye geri düşer ve bir belgenin üretilmesini asla durdurmaz

Alt kümeleme bir nedenden dolayı pahalıdır. Bir alt küme inşa etmek, glyph kapanışını yürümek, loca ve glyf'i yeniden yazmak, cmap ve hmtx'i yeniden inşa etmek ve PDF'in adresleyebileceği bir CID eşlemesi yaymak demektir. Tek bir belge için o maliyet gürültü içinde kaybolur. Bir döngüde belge üreten bir rapor sunucusu için çalışmadaki en büyük tek CPU zamanı bloğu çoğunlukla budur

Bir önbellek isabetini mümkün kılan nedir?

Dört şey eşleşmelidir: yazı tipi içeriği, kullanılan glyph kümesi, alt küme modu ve önbellek şeması. Birini kaçırın ve HotPDF baştan alt kümeler, çünkü bir alt küme yalnızca yine de byte olarak özdeş olacağı zaman yeniden kullanılabilirdir

Glyph kümesi insanları şaşırtan koşuldur. Tek bir müşteri adıyla ayrışan iki fatura farklı glyph kümeleri kullanır ve bu nedenle farklı alt kümeler ve farklı önbellek girdileri üretir. Önbellek, belgeler bir glyph repertuarını paylaştığında karşılığını verer; sabit bir şablondan ekstreler, değişken verisi sayısal olan formlar, tek bir ürün veri tabanından çizilen kataloglar; ve her belge büyük bir CJK yazı tipinin farklı bir dilimini çizdiğinde hiç karşılık vermez. Hangi durumda olduğunuzu varsaymadan önce ölçün

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;

Önbelleğin işe yaradığını nasıl bilirsiniz?

GetFontSubsetCacheInfo dokuz sayaç döndürür ve ilk ikisi arasındaki oran soruyu doğrudan yanıtlar. HitCount ve MissCount isabet oranını verir. WriteCount ve EvictionCount, girdilerin yeniden kullanılmak için yeterince uzun hayatta kalıp kalmadığını yoksa çok küçük bir bütçe tarafından dışarı itilip itilmediğini gösterir. CurrentBytes ve FileCount şu an diskte ne olduğunu raporlar

Geri kalan üçü uyarı vermeye değer olanlardır. CorruptCount, doğrulamada başarısız olan ve kaldırılan girdileri sayar; temiz olmayan bir kapanmadan sonra birkaç tanesi normaldir, sürekli bir akış depolamanın güvenilmez olduğu anlamına gelir. RejectedCount, kullanılmadan önce reddedilen girdileri sayar. WriteFailureCount hiç yazılamayan girdileri sayar; bu da çoğunlukla yazı tipleriyle ilgili bir şeyden ziyade klasörde bir izinler sorunu olduğu anlamına gelir. Bu üçünün hiçbiri belge üretimini durdurmaz, ki bakmanız gereken neden tam olarak budur: sessizce hiç yazmayan bir önbellek dışarıdan çalışan bir önbellekle aynı görünür, CPU faturası dışında

Çıkarma, bütçeler ve birini küçülttüğünüz an

FontSubsetCacheMaxBytes öntanımlı olarak 268435456 bayttır, yani 256 MiB, ve çalışma zamanında düşürülebilir. Düşürmek, bir sonraki yazmayı beklemek yerine en-az-yakın-kullanılan çıkarmayı hemen tetikler, dolayısıyla disk baskısına tepki veren bir hizmet boş alanı denetlemediği bir sonraki noktada değil, karar verdiği an serbest bırakabilir

FontSubsetCacheFolder'ı boş bir dizeye ayarlamak, zaten depolanmış hiçbir şeyi temizlemeden ve yazı tipi çıktısının tek bir baytını değiştirmeden disk katmanını devre dışı bırakır. Sorun giderme sırasında önbelleği yalıtmak istediğinizde uzanacağınız özellik budur: kapatın, aynı toplu işi çalıştırın ve üretilen PDF'leri karşılaştırın. Özdeş olmalılar, çünkü önbellek bir politikayı değil bir sonucu depolar

Bir girdi hasarlı olduğunda önbellek ne yapar?

Onu kaldırır ve normal olarak alt kümeler. Hatalı oluşturulmuş veya kesilmiş girdiler, alt küme bir PDF akışına ulaşmadan önce reddedilir; bu da tasarımın en çok önem taşıyan parçasıdır: bir belgeye karışmış hasarlı bir önbellek girdisi, bozuk bir yazı tipi programına sahip bir PDF üretirdi ve o başarısızlık nedeninden çok uzakta yüzeye çıkardı; bir görüntüleyicide, bir müşterinin makinesinde, haftalar sonra

Yazmalar atomiktir, dolayısıyla bir okuyucu asla yarım yazılmış bir girdi gözlemlemez ve yazma sırasındaki bir çöküş önbelleği zehirli yerine tutarlı bırakır. Sıkı alt küme girdileri, PDF/A yazı tipi sözlüklerinin gerektirdiği CID yeniden eşleme verisini korur, dolayısıyla önbelleğe alınmış bir alt küme yine de uyumlu bir alt kümedir; arşiv çıktısı geçerli kalmak için önbelleği atlamak zorunda değildir

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

Gerçek bir dağıtımda klasör nereye konur?

Üç özellik buna karar verir: klasör, hizmetin çalıştığı hesap tarafından yazılabilir olmalıdır, bir ağ paylaşımı yerine yerel depolamada durmalıdır ve bir dağıtım adımının sildiği bir dizinin içinde olmamalıdır. Bir paylaşımdaki önbellek her kaçırmayı bir gidiş-dönüşe ve her isabeti ikiye çevirir; yükleyicinin yeniden oluşturduğu bir uygulama klasörü altındaki önbellek, her güncellemeden sonra soğuk başlayan bir önbellektir

Çok örnekli hizmetler için, depolamanın eşzamanlı atomik değiştirmeyi beklediğiniz gibi ele aldığını doğrulamadıkça her örneğe kendi klasörünü verin. Yinelenen bir girdinin maliyeti bir ek alt kütleme geçişidir; paylaşılan önbellek yarışını hata ayıklamanın maliyeti bir öğleden sonradır

Ne zaman başka bir şeye uzanılır?

Önbellek yinelenen işi azaltır. İlk belgenin işini azaltmaz ve glyph kümeleri asla yinelenmeyen bir iş yüküne yardımcı olmaz. Çıktınız öngörülemeyen metinlerde kullanılan tek bir dev CJK yazı tipiyle domine ediliyorsa, daha etkili kol alt kütleme kapanışının kendisidir; hangi glyph'lerin çekildiği ve neden; yazı tipi alt küme kapanışı ve glyph'leri şekillendirme notlarında ele alınır. Toplu işiniz nedenleri hiç yazı tipleri olmadan çıkan bir yavaşlıksa, yazı tipleri ve görsellerle rapor çıktısı yazısı diğer zamanın genellikle nereye gittiğini gösterir ve EndDoc yazı tipi alt küme sıralama hatası vakası incelemesi, alt kütleme doğruluğu ile alt kütleme hızının ayrı sorunlar olduğunun bir anımsatmasıdır

HotPDF, Delphi ve C++Builder için yerel bir VCL PDF bileşenidir ve alt küme önbelleği kitaplığın bir eklenti hizmeti değil parçasıdır, dolayısıyla bir rapor sunucusu tek bir klasör yolu ayarlayarak onu alır; tam yazı tipi ve performans özellik listesi için HotPDF bileşeni sayfasına bakın