Benchmark load/save yang jujur untuk PDF Library for Delphi mengukur waktu LoadFromFile dan SaveToFile dengan QueryPerformanceCounter, menyimpan tick mentah dan frekuensi counter, menjalankan baseline dan kandidat dalam pasangan A/B, B/A, A/B bergantian, menolak mulai selama beban CPU di atas 25%, menolak setiap hasil yang sebaran range-ke-mediannya melebihi 15%, dan membuang setiap pengukuran yang PDF tersimpannya gagal validasi struktural, rendering, atau semantik. Daftar itu terdengar seperti birokrasi sampai pertama kali klaim "20% lebih cepat" menguap saat diulang. Berikut ini adalah bagaimana corpus probe khusus dan comparison runner-nya sampai ke sana, termasuk run saat mesinnya benar-benar terlalu sibuk untuk mengukur apa pun dan harness-nya dengan benar mengatakannya
Kenapa Benchmark PDF Delphi Melaporkan Nol Detik?
Benchmark load PDF melaporkan nol detik ketika tick jamnya lebih kasar daripada operasi yang diukurnya, dan GetTickCount64 adalah jam bertipe itu: ia mengembalikan milidetik, tapi di Windows ia hanya maju saat interrupt system timer menyala, umumnya setiap 15,6 ms. Port FPC dari demo benchmark huge-file di PDF Library for Delphi memakainya karena TStopwatch tidak tersedia di toolchain itu, dan ia mencatat waktu berjalan sampai tiga tempat desimal. Memuat gambar CAD kecil atau dokumen tagged pendek selesai jauh di dalam satu langkah timer, jadi demo itu kadang mencetak 0.000 untuk load yang jelas mengerjakan pekerjaan nyata
function ElapsedSeconds(StartTick: QWord): Double;
begin
Result:= (GetTickCount64- StartTick)/ 1000.0;
end;
// di dalam loop operasi
Lib:= TPDFlib.Create;
try
Lib.OnProgress:= Reporter.Progress;
Started:= GetTickCount64;
LoadCode:= Lib.LoadFromFile(InputFile, Password);
...
Nol lebih buruk daripada angka yang tak presisi, karena setiap perbandingan yang Anda bangun di atasnya membagi dengan nol itu. Paired comparison runner memperlakukan setiap arm dengan minimum nol sebagai inkonklusif dengan alasan "Zero duration prevents a meaningful ratio", yang merupakan penolakan yang benar, tapi itu juga berarti pengukuran demo meninggalkan celah pengukuran tepat di tempat file pendek hidup. Demo yang sama juga memasang callback OnProgress, jadi pengukurannya menyertakan overhead callback yang seharusnya tidak dibawa pengukuran load/save yang bersih, dan angka demo yang terarsip tidak bisa dipertukarkan dengan apa pun yang diukur belakangan
Mengukur LoadFromFile dan SaveToFile dengan QueryPerformanceCounter
Console probe khususnya, Tests/CorpusLoadSave.dpr, mengukur dua operasi per file input dengan QueryPerformanceCounter: LoadFromFile plus pembacaan PageCount, dan LoadFromFile plus PageCount plus SaveToFile. Setiap operasi mendapat instance TPDFlib yang baru dan tanpa progress callback, dan constructor serta destructor instance berada di luar region yang diukur, demikian pula penulisan CSV dan semua validasi output. Counter dibaca tepat sebelum load dan tepat setelah panggilan library terakhir, dan LastErrorCode diambil hanya setelah pembacaan kedua
Lib:= TPDFlib.Create;
try
if not QueryPerformanceCounter(Started) then
raise Exception.Create('Performance counter unavailable');
Code:= Lib.LoadFromFile(WideString(SourceFile), '');
if Code= 1 then
begin
Pages:= Lib.PageCount;
if Save then Code:= Lib.SaveToFile(WideString(SavedFile));
end;
if not QueryPerformanceCounter(Finished) then
raise Exception.Create('Performance counter unavailable');
ErrorCode:= Lib.LastErrorCode;
finally
Lib.Free;
end;
Ticks:= Finished- Started;
if Ticks< 0 then
raise Exception.Create('Performance counter moved backwards');
Probe menulis jumlah tick mentah dan frekuensi counter di samping detik hasil hitung, diformat dengan sembilan tempat desimal dan pemisah desimal . yang tetap, jadi siapa pun bisa menghitung ulang hasil baginya dari CSV alih-alih mempercayainya begitu saja. Di build FPC Win64, sampel CAD termuat dalam 8.888 tick pada 10.000.000 tick per detik, tercatat sebagai 0.000888800 detik — sebuah observasi yang timer lama akan bulatkan ke nol. Probe sengaja tidak memotong nilai pendek, mengganti dengan durasi minimum, atau mengurangi estimasi overhead timer, dan ia tetap menulis kedua baris dengan exit code bukan nol ketika panggilan library gagal. Sembilan digit bukan berarti akurasi sih: presisi tercatat yang lebih banyak tak berkata apa-apa soal repeatability, dan observasi yang bising atau nol tetap harus ditolak di hilir
if not QueryPerformanceFrequency(Frequency) or (Frequency<= 0) then
raise Exception.Create('Performance counter frequency unavailable');
NumberFormat:= TFormatSettings.Create;
NumberFormat.DecimalSeparator:= '.';
...
Rows.Add(CSV(ExtractFileName(SourceFile))+ ','+ CSV(Operation)+ ','+
FormatFloat('0.000000000', Ticks/ Frequency, NumberFormat)+ ','+
IntToStr(Code)+ ','+ IntToStr(ErrorCode)+ ','+ IntToStr(Pages)+ ','+
IntToStr(Ticks)+ ','+ IntToStr(Frequency));
Apa yang Membuat Perbandingan Waktu Load/Save PDF Layak Dipercaya?
Perbandingan waktu antara dua build PDF Library for Delphi hanya layak dipercaya ketika urutan mulai, kondisi mulai, dan sebarannya semuanya terkendali dan tercatat, jadi comparison runner menjadwalkan setidaknya tiga pasangan dalam urutan A/B, B/A, A/B. Selalu menjalankan baseline lebih dulu diam-diam menyodorkan file cache yang lebih hangat dan state termal yang berbeda pada kandidat; mengganti urutannya menyebarkan bias itu ke kedua arm alih-alih mengkreditkannya ke satu arm. Sebelum setiap arm, runner meng-hash file input lengkap dengan SHA-256, yang sekaligus memverifikasi bahwa tidak ada yang berubah dan membaca lebih dulu byte yang sama untuk kedua arm, dan ia meng-hash dua executable serta alat validasinya lagi setelah setiap run supaya binary yang dibangun ulang tak bisa menyelinap ke tengah sebuah seri
Runner kemudian menyampling utilisasi CPU seluruh mesin sekali per detik dan memulai arm hanya ketika sebuah sampel turun ke 25% atau di bawahnya, menunggu paling lama 30 detik sebelum mencatat percobaannya sebagai ditolak. Gate itu mengendalikan kondisi mulai dan tidak lebih: ia tidak mengisolasi mesin selama run, dan power state, thermal throttling, pekerjaan latar, serta caching OS tetap bisa menggeser angkanya. Maka filter kedua bersifat statistik dalam arti yang paling polos. Untuk setiap operasi, runner menghitung range dibagi median untuk arm baseline, arm kandidat, dan distribusi rasio pasangan kandidat/baseline, dan jika salah satu dari ketiganya melebihi 0,15 hasilnya diberi label noisy alih-alih dilaporkan sebagai temuan
Kenapa Same-Binary Control Membuktikan Repeatability, Bukan Kecepatan?
Same-binary control menjalankan executable identik sebagai baseline dan kandidat, jadi rasio mendekati 1,0 hanya bisa membuktikan bahwa setup pengukurannya mengulang dirinya sendiri; ia tidak akan pernah bisa menunjukkan bahwa sebuah implementasi jadi lebih cepat. Kontrol ketat pertama pada 2026-09-21 memakai probe FPC Win64 resolusi tinggi terhadap panduan tagged 70 halaman yang diakui, dan keenam start semuanya ditolak karena sampel CPU berkisar 26,5% sampai 93,8%. Laporannya berisi kegagalan tanpa agregat, dan itu persis hasil yang Anda inginkan saat mesinnya sibuk. Cobaan ulang di hari yang sama dengan input identik byte, executable probe yang sama, dan ambang yang tak berubah menerima keenam start dalam 3 detik; setiap sebaran range-ke-median mendarat antara 0,019 dan 0,054, dan median rasionya 1,0084 untuk LoadFromFile dan 0,9872 untuk LoadFromFile + SaveToFile
Sepasang angka itu menetapkan jendela observasi berkualifikasi dan tidak lebih. Ketika kedua binary berbeda, run yang stabil diberi label perbandingan deskriptif, dengan catatan eksplisit bahwa rasionya adalah observasi, bukan signifikansi statistik atau klaim percepatan. Disiplin ini paling berarti saat Anda memvalidasi optimasi tertarget seperti yang dijelaskan di profiling PDF Library for Delphi dan mengganti hot path dengan hash index: profiler mengatakan ke mana waktu pergi, tapi hanya paired run terkendali pada dokumen nyata yang mengatakan apakah perubahannya selamat menyentuh seluruh pipeline. Satu batas lagi yang layak diucapkan lantang — normal-save menyertakan loading, dan peak working set yang dicatat runner bersifat process-wide, jadi tak satu pun dari itu adalah memori yang bisa diatribusikan ke penyimpanan saja
Tiga Gate Output dan Matriks Empat Compiler
Tidak ada pengukuran PDF Library for Delphi yang dihitung kecuali file yang dihasilkannya lolos tiga gate independen, karena save yang cepat menulis PDF rusak bukanlah save yang lebih cepat. Benchmark pertama-tama memeriksa bahwa kedua operasi mengembalikan 1 dan melaporkan jumlah halaman yang diakui, lalu memvalidasi satu-satunya PDF tersimpan dalam urutan ini:
- Struktur: checker PDF independen harus meloloskan file tersimpan tanpa error atau warning
- Rendering: setiap halaman dirender dalam state bawaannya, dan set SHA-256 gambar per halaman harus cocok persis dengan rendering referensi dari sumber yang diakui
- Semantik nonvisual: perbandingan semantik terpisah terhadap sumber mencakup properti terpilih yang tak bisa ditunjukkan piksel, termasuk struktur optional-content dan measurement dalam cakupan terdokumentasinya
Dengan gate-gate itu terpasang, matriks corpus lokal penuh menjalankan probe di FPC Win32, FPC Win64, Delphi Win32, dan Delphi Win64 atas 12 PDF yang diakui dengan 1.612 halaman sumber, menghasilkan 48 pasangan sample/target dan 6.448 halaman output tervalidasi tanpa perbedaan semantik terpilih. Seluruh 96 pengukuran operasi mempertahankan nilai counter mentah positif yang konsisten dengan detik yang dilaporkan, dan nilai-nilai itu sengaja tidak diagregasi menjadi tabel kecepatan lintas compiler, karena matriksnya adalah bukti fungsional alih-alih perbandingan terkendali. Jalur load/save juga tidak mengklaim mendekode setiap gambar embedded, memvalidasi signature, menjalankan XFA, atau mensertifikasi PDF/UA; kalau Anda perlu menilai throughput rendering alih-alih biaya load/save, batasan konkurensi di rendering halaman paralel dan thread safety di PDF Library for Delphi adalah titik mulai yang lebih tepat
Kesimpulan praktisnya pendek: simpan counter mentah, ganti urutannya, beri gate pada mulai, tolak sebaran yang bising, dan jangan pernah mengukur output yang belum Anda validasi. Aturan-aturan itulah yang membuat PDF Library for Delphi bisa mengatakan "tidak ada perubahan terukur" sekendali dia mengatakan "lebih cepat", dan source probe yang sama ter-compile tanpa perubahan di Delphi dan FPC untuk Win32 dan Win64. Anda bisa meninjau library-nya, load/save API-nya, dan compiler yang didukung di halaman produk PDF Library for Delphi