HotPDF สามารถเก็บสับเซตแบบอักษร TrueType และ OpenType บนดิสก์แล้วใช้ซ้ำข้ามเอกสารและข้ามการรันโพรเซส ทำให้ชุดงานที่เรนเดอร์เอกสารสถานะหนึ่งหมื่นฉบับด้วยแบบอักษรเดียวกันสามตัว ทำ subsetting แบบอักษรเหล่านั้นเพียงครั้งเดียวแทนหนึ่งหมื่นครั้ง แคชกำหนดค่าด้วยสองคุณสมบัติ ตรวจสอบด้วย record เดียว และปลอดภัยที่จะปล่อยไว้ ความล้มเหลวของแคชจะกลับไปใช้ subsetting ในหน่วยความจำปกติและไม่หยุดเอกสารจากการถูกผลิตเป็นอันขาด
การทำสับเซตแพงด้วยเหตุผล การสร้างสับเซตหมายถึงการเดิน glyph closure เขียน loca และ glyf ใหม่ สร้าง cmap และ hmtx ใหม่ แล้วปล่อยการแมป CID ที่ PDF จะจัดที่อยู่ได้ สำหรับเอกสารหนึ่งค่าใช้จ่ายนั้นกลืนไปกับสัญญาณรบกวน สำหรับเซิร์ฟเวอร์รายงานที่ผลิตเอกสารในลูป มันมักเป็นบล็อกเวลา CPU เดียวที่ใหญ่ที่สุดในการรัน
อะไรทำให้แคช hit เป็นไปได้
สี่สิ่งต้องตรงกัน คือเนื้อหาแบบอักษร ชุด glyph ที่ใช้ โหมดสับเซต และ schema ของแคช พลาดอันใดอันหนึ่งแล้ว HotPDF จะทำสับเซตใหม่ตั้งแต่ต้น เพราะสับเซตใช้ซ้ำได้ก็ต่อเมื่อมันจะเหมือนกันไบต์ต่อไบต์อยู่แล้วเท่านั้น
ชุด glyph คือเงื่อนไขที่ทำให้คนประหลาดใจ ใบแจ้งหนี้สองใบที่ต่างกันเพียงชื่อลูกค้าหนึ่งชื่อใช้ชุด glyph ต่างกัน จึงผลิตสับเซตและ cache entry ต่างกัน แคชคุ้มค่าเมื่อเอกสารแชร์คลัง glyph ร่วมกัน — สถานะจากเทมเพลตคงที่ ฟอร์มที่ข้อมูลผันแปรเป็นตัวเลข แคตตาล็อกที่ดึงจากฐานข้อมูลผลิตภัณฑ์เดียว — และไม่คุ้มเลยเมื่อทุกเอกสารวาดชิ้นส่วนต่าง ๆ ของแบบอักษร CJK ขนาดใหญ่ วัดก่อนสมมติว่าคุณอยู่ในกรณีใด
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;
คุณจะรู้ได้อย่างไรว่าแคชกำลังทำงานอยู่
GetFontSubsetCacheInfo คืนเก้าตัวนับ และอัตราส่วนระหว่างสองตัวแรกตอบคำถามนั้นตรง ๆ HitCount และ MissCount ให้ hit rate WriteCount และ EvictionCount แสดงว่า entry อยู่รอดพอที่จะใช้ซ้ำหรือกำลังถูกดันออกด้วยงบประมาณที่เล็กเกินไป CurrentBytes และ FileCount รายงานสิ่งที่อยู่บนดิสก์ตอนนี้
สามตัวที่เหลือคือสิ่งที่คุ้มค่าจะแจ้งเตือน CorruptCount นับ entry ที่ตก validation และถูกเอาออก — ไม่กี่ตัวหลังการปิดระบบที่ไม่สะอาดเป็นเรื่องปกติ สายที่ต่อเนื่องหมายถึงพื้นที่จัดเก็กไม่น่าเชื่อถือ RejectedCount นับ entry ที่ถูกปฏิเสธก่อนใช้ WriteFailureCount นับ entry ที่เขียนไม่ได้เลย ซึ่งมักหมายถึงปัญหาสิทธิ์บนโฟลเดอร์มากกว่าเรื่องของแบบอักษร ไม่มีสามตัวนี้หยุดการสร้างเอกสาร ซึ่งเป็นเหตุผลว่าทำไมคุณต้องดูมัน แคชที่เงียบ ๆ ไม่เขียนเลยดูเหมือนกันจากภายนอกกับแคชที่ทำงานได้ เว้นเฉพาะบิล CPU
การขับออก งบประมาณ และช่วงเวลาที่คุณย่อขนาดมัน
FontSubsetCacheMaxBytes มีค่าเริ่มต้น 268435456 ไบต์ คือ 256 MiB และสามารถลดได้ที่รันไทม์ การลดกระตุ้นให้เกิด least-recently-used eviction ทันทีแทนที่จะรอการเขียนครั้งถัดไป ทำให้บริการที่ตอบสนองต่อแรงกดดันของดิสก์สามารถคืนพื้นที่ในช่วงเวลาที่มันตัดสินใจ ไม่ใช่ในช่วงเวลาถัดไปที่มันไม่ได้ควบคุม
การตั้ง FontSubsetCacheFolder เป็นสตริงว่างจะปิด disk tier โดยไม่ล้างสิ่งที่จัดเก็บไว้แล้ว และไม่เปลี่ยนไบต์เดียวของเอาต์พุตแบบอักษร นี่คือคุณสมบัติที่ควรเอื้อมไปเมื่อต้องการแยกแคชระหว่างการแก้ไขปัญหา ปิดมัน รันชุดงานเดียวกัน แล้วเปรียบเทียบ PDF ที่ผลิต พวกมันควรเหมือนกันทุกประการ เพราะแคชเก็บผลลัพธ์ ไม่ใช่นโยบาย
สิ่งที่แคชทำเมื่อ entry เสียหาย
มันเอาออกแล้วทำสับเซตตามปกติ entry ที่ผิดรูปแบบหรือถูกตัดทอนถูกปฏิเสธก่อนที่สับเซตจะไปถึง PDF stream ได้ ซึ่งเป็นส่วนของการออกแบบที่สำคัญที่สุด cache entry ที่เสียหายที่เข้าไปในเอกสารได้จะผลิต PDF ที่มี font program พัง และความล้มเหลวนั้นจะปรากฏไกลจากสาเหตุ — ในตัวอ่าน บนเครื่องของลูกค้า หลายสัปดาห์ให้หลัง
การเขียนเป็น atomic ทำให้ตัวอ่านไม่เคยสังเกต entry ที่เขียนครึ่ง ๆ และการล้มเหลวกลางการเขียนทิ้งแคชให้สอดคล้องแทนที่จะเป็นพิษ compact subset entry ยังคงเก็บข้อมูลการแมป CID ที่ font dictionary ของ PDF/A กำหนด สับเซตที่แคชจึงยังคงเป็นสับเซตที่สอดคล้อง — เอาต์พุตเก็บถาวรไม่ต้องบายพาสแคชเพื่อให้ถูกต้อง
// 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');
จะวางโฟลเดอร์ที่ไหนในการปรับใช้จริง
สามคุณสมบัติตัดสินเรื่องนี้ โฟลเดอร์ต้องเขียนได้โดยบัญชีที่บริการรันเป็น มันควรอยู่บนพื้นที่จัดเก็บในเครื่องแทนเครือข่ายแชร์ และไม่ควรอยู่ในไดเรกทอรีที่ขั้นตอนการปรับใช้ล้าง แคชบนแชร์เปลี่ยน miss ทุกครั้งให้เป็น round trip และ hit ทุกครั้งให้เป็นสองรอบ แคชใต้โฟลเดอร์แอปพลิเคชันที่ตัวติดตั้งสร้างใหม่คือแคชที่เริ่มเย็นหลังทุกการอัปเดต
สำหรับบริการหลายอินสแตนซ์ ให้แต่ละอินสแตนซ์มีโฟลเดอร์ของตัวเอง เว้นแต่คุณยืนยันแล้วว่าพื้นที่จัดเก็กจัดการการแทนที่แบบ atomic พร้อมกันตามที่คุณคาดหวัง ต้นทุนของ entry ที่ซ้ำกันคือการทำสับเซตพิเศษหนึ่งรอบ ต้นทุนของการดีบัก race ของแคชที่แชร์คือบ่ายหนึ่งวัน
เมื่อใดควรหาทางเลือกอื่น
แคชลดงานที่ซ้ำกัน มันไม่ได้ลดงานของเอกสารแรก และไม่ช่วยเวิร์กโหลดที่ชุด glyph ไม่เคยซ้ำ หากเอาต์พุตของคุณถูกครอบงำด้วยแบบอักษร CJK ขนาดมหึมาที่ใช้กับข้อความที่คาดเดาไม่ได้ lever ที่ได้ผลมากกว่าคือ closure ของการทำสับเซตเอง — glyph ใดถูกดึงเข้ามา และเพราะเหตุใด — ซึ่งครอบคลุมในบันทึกของ closure ของสับเซตแบบอักษรและการจัดรูป glyph หากชุดงานของคุณช้าด้วยเหตุผลที่กลายเป็นว่าไม่ใช่แบบอักษรเลย คู่มือ เอาต์พุตรายงานพร้อมแบบอักษรและรูปภาพ แสดงว่าเวลาอื่น ๆ มักไปอยู่ที่ใด และกรณีศึกษาของ บั๊กการจัดลำดับสับเซตแบบอักษรที่ EndDoc เป็นเครื่องเตือนใจว่าความถูกต้องของการทำสับเซตและความเร็วของการทำสับเซตเป็นปัญหาแยกกัน
HotPDF เป็นคอมโพเนนต์ PDF แบบ VCL พื้นเมืองสำหรับ Delphi และ C++Builder และ subset cache เป็นส่วนหนึ่งของไลบรารี ไม่ใช่บริการเสริม เซิร์ฟเวอร์รายงานจึงได้มันโดยตั้งเส้นทางโฟลเดอร์เดียว — ดู หน้าคอมโพเนนต์ HotPDF สำหรับรายการคุณสมบัติแบบอักษรและประสิทธิภาพฉบับสมบูรณ์