Sąžiningas PDF Library for Delphi įkėlimo ir įrašymo benchmarkas matuoja LoadFromFile ir SaveToFile su QueryPerformanceCounter, saugo žalius taktus ir skaitiklio dažnį, leidžia bazinę ir kandidatinę versijas kaitaliojamomis A/B, B/A, A/B poromis, atsisako startuoti, kol CPU apkrova laikosi aukščiau 25%, atmeta bet kokį rezultatą, kurio rangos ir medianos santykis viršija 15%, ir išmeta kiekvieną matavimą, kurio įrašytas PDF nepraeina struktūrinės, atvaizdavimo ar semantinės patikros. Tas sąrašas skaitosi kaip biurokratija, kol pirmąkart „20% greičiau“ teiginys išgaruoja pakartotinai paleidus. Toliau – kaip ten atėjo atskiras korpuso zondas ir jo palyginimo vykdytojas, įskaitant paleidimą, kai mašina buvo tiesiog per užsiėmusi ką nors išmatuoti, o matavimo rėmas teisingai tą ir parašė
Kodėl Delphi PDF benchmarkas praneša nulines sekundes?
PDF įkėlimo benchmarkas praneša nulines sekundes, kai jo laikrodis tiksi šiurkščiau nei matuojama operacija, o GetTickCount64 yra būtent toks laikrodis: jis grąžina milisekundes, bet Windows sistemoje pasislenka tik sužibus sistemos laikmačio pertraukimui, paprastai kas 15,6 ms. Didelių failų benchmark demo FPC varianta PDF Library for Delphi jį naudojo todėl, kad TStopwatch toje įrankių grandinėje neprieinamas, ir įrašinėjo praėjusį laiką trimis dešimtainiais skaitmenimis. Mažo CAD brėžinio arba trumpo tagged dokumento įkėlimas baigiasi gerokai viename laikmačio žingsnyje, tad demo kartais spausdindavo 0.000 už įkėlimą, kuris, aišku, dirbo tikrą darbą
function ElapsedSeconds(StartTick: QWord): Double;
begin
Result:= (GetTickCount64- StartTick)/ 1000.0;
end;
// operacijos kilpos viduje
Lib:= TPDFlib.Create;
try
Lib.OnProgress:= Reporter.Progress;
Started:= GetTickCount64;
LoadCode:= Lib.LoadFromFile(InputFile, Password);
...
Nulis yra blogesnis už netikslų skaičių, nes kiekvienas ant jo pastatytas palyginimas dalija iš jo. Porinis palyginimo vykdytojas bet kurią šaką su nuliniu minimumu vertina kaip nieko neįrodančią su priežastimi „Nulinė trukmė neleidžia gauti prasmingo santykio“ – tai teisingas atsisakymas, bet jis taip pat reiškia, kad demo matavimai paliko tuščią vietą būtent ten, kur gyvena trumpi failai. Tas pats demo įdiegia ir OnProgress atgalinį iškvietimą, todėl jo matavimai neša callback išlaidas, kurių švarus įkėlimo ir įrašymo matavimas nešioti neturėtų, o archyvuoti demo skaičiai nekeičiami jokiais vėliau išmatuotais
LoadFromFile ir SaveToFile matavimas su QueryPerformanceCounter
Atskiras konsolinis zondas Tests/CorpusLoadSave.dpr matuoja dvi operacijas kiekvienam įvedimo failui su QueryPerformanceCounter: LoadFromFile plius PageCount perskaitymas ir LoadFromFile plius PageCount plius SaveToFile. Kiekviena operacija gauna šviežią TPDFlib egzempliorių ir jokio progress atgalinio iškvietimo, o egzemplioriaus konstruktorius ir destruktorius stovi už matuojamos srities ribų – kaip ir CSV rašymas bei visa išvesties patikra. Skaitiklis skaitomas iškart prieš įkėlimą ir iškart po paskutinio bibliotekos iškvietimo, o LastErrorCode imamas tik po antrojo skaitymo
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');
Zondas įrašo žalių taktų skaičių ir dažnį šalia išvestinių sekundžių, suformatuotų devyniais dešimtainiais skaitmenimis ir fiksuotu . skyrikliu, tad kas nori, gali perskaičiuoti dalmenį iš CSV, o ne juo aklai tikėti. FPC Win64 versijoje CAD pavyzdys įkėlo per 8 888 taktus esant 10 000 000 taktų per sekundę, užrašyta kaip 0.000888800 sekundės – stebėjimas, kurį senasis laikmatis būtų apvalinęs iki nulio. Zondas sąmoningai nenukerpa trumpų reikšmių, nekviečia minimalios trukmės joms pakeisti ir neatima įvertintos laikmačio pridėtinės išlaidos, o kai bibliotekos iškvietimas žlunga, vis tiek įrašo abi eilutes su nenuliniu išėjimo kodu. Devyni skaitmenys, tačiau, dar nėra tikslumas: daugiau užrašyto tikslumo nieko nesako apie kartojamumą, o triukšmingi ar nuliniai stebėjimai vis tiek turi būti atmetami vėlesnėje grandyje
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));
Kas daro PDF įkėlimo ir įrašymo matavimų palyginimą patikimu?
Dviejų PDF Library for Delphi versijų matavimų palyginimas yra patikimas tik tada, kai starto tvarka, starto sąlygos ir išsibarstymas yra kontroliuojami ir įrašomi, todėl palyginimo vykdytojas suplanuoja bent tris poras A/B, B/A, A/B tvarka. Nuolatinis bazinės versijos paleidimas pirmoje vietoje kandidatui tyliai įteikia šiltesnį failų podėlį ir kitokią temperatūrinę būseną; tvarkos kaitaliojimas paskirsto tą šališkumą abiejoms šakoms, o ne sukaupia jį vienoje. Prieš kiekvieną šaką vykdytojas apskaičiuoja pilno įvedimo failo SHA-256, kas vienu metu ir patikrina, kad niekas nepasikeitė, ir iš anksto perskaito tuos pačius baitus abiem šakoms, o po kiekvieno paleidimo dar kartą suhašuoja abu vykdomuosius failus ir patikros įrankius, kad per naujo sukompiliuotas dvejetainis failas negalėtų paslysti į serijos vidurį
Tada vykdytojas kas sekundę paima visos mašinos CPU naudojimo pavyzdį ir paleidžia šaką tik tada, kai pavyzdys nukrenta iki 25% ar žemiau, laukdamas ne ilgiau kaip 30 sekundžių, prieš užregistruodamas bandymą kaip atmestą. Tie vartai kontroliuoja starto sąlygą ir nieko daugiau: jie neizoliuoja mašinos paleidimo metu, o maitinimo būsena, temperatūrinis sulėtėjimas, foninis darbas ir OS podėliavimas vis tiek gali pajudinti skaičius. Todėl antras filtras yra statistinis pačia paprasčiausia prasme. Kiekvienai operacijai vykdytojas apskaičiuoja rangos ir medianos santykį bazinės šakos, kandidatinės šakos ir porinių kandidato/bazė santykių pasiskirstymo atžvilgiu, ir jei kuris nors iš trijų viršija 0,15, rezultatas pažymimas kaip triukšmingas, o ne pranešamas kaip išvada
Kodėl to paties dvejetainio failo kontrolė įrodo kartojamumą, o ne greitį?
To paties dvejetainio failo kontrolė kaip bazę ir kandidatą paleidžia identiškus vykdomuosius failus, todėl santykis prie 1,0 gali įrodyti tik tai, kad matavimo prietaisas kartojasi; jis niekada negali parodyti, kad implementacija tapo greitesnė. Pirmoji griežta kontrolė 2026-09-21 naudojo didelės raiškos FPC Win64 zondą prieš priimtą 70 puslapių tagged vadovą, ir visi šeši startai buvo atmesti, nes CPU pavyzdiai svyravo nuo 26,5% iki 93,8%. Ataskaitoje buvo žlugimai ir jokių agregatų – lygiai tas išėjimas, kurio norite, kai mašina užsiėmusi. Tos pačios dienos pakartojimas su baitas į baitą identiškais įvedimais, tuo pačiu zondo vykdomuoju failu ir nepakeistais slenksčiais priėmė visus šešis startus per 3 sekundes; kiekvienas rangos ir medianos santykis pateko tarp 0,019 ir 0,054, o santykių medianos buvo 1,0084 LoadFromFile ir 0,9872 LoadFromFile + SaveToFile
Ta skaičių pora nustato tik sąlyginį stebėjimo langą ir nieko daugiau. Kai du dvejetainiai failai skiriasi, stabilus paleidimas žymimas kaip aprašomasis palyginimas, su aiškia pastaba, kad santykiai yra stebėjimai, o ne statistinis reikšmingumas ar pagreitėjimo teiginys. Ta disciplina svarbiausia, kai tikrinate tikslinius optimizavimus, tokius kaip aprašyti straipsnyje apie PDF Library for Delphi profiliavimą ir karštų kelių pakeitimą hašo indeksais: profileris pasako, kur keliauja laikas, bet tik kontroliuotas porinis paleidimas ant tikrų dokumentų pasako, ar pakeitimas išgyveno susidūrimą su visu konvejeriu. Dar viena riba, verta pasakyti garsiai — normal-save apima įkėlimą, o vykdytojo registruojamas pikinis darbinis rinkinys yra viso proceso, tad nė viena jo dalis nėra atmintis, priskirtina vien tik įrašymui
Trys išvesties vartai ir keturių kompiliatorių matrica
Nė vienas PDF Library for Delphi matavimas neskaitomas, nebent jo pagamintas failas praeina tris nepriklausomus vartus, nes įrašymas, kuris greitai užrašo sugadintą PDF, nėra greitesnis įrašymas. Benchmarkas pirmiausia patikrina, kad abi operacijos grąžino 1 ir pranešė priimtą puslapių skaičių, tada patikrina vieną įrašytą PDF tokia tvarka:
- Struktūra: nepriklausomas PDF tikrintuvas turi praleisti įrašytą failą be klaidų ar perspėjimų
- Atvaizdavimas: kiekvienas puslapis atvaizduojamas numatytoje būsenoje, o puslapio paveikslėlio SHA-256 rinkinys turi tiksliai sutapti su priimto šaltinio etaloniniu atvaizdavimu
- Nevizualinė semantika: atskiras semantinis palyginimas su šaltiniu dengia pasirinktas savybes, kurių pikseliai negali parodyti, įskaitant optional-content ir matavimo struktūras jų dokumentuotame taikymo lauke
Turint tuos vartus, pilna vietinio korpuso matrica paleido zondą FPC Win32, FPC Win64, Delphi Win32 ir Delphi Win64 aplinkose per 12 priimtų PDF su 1 612 šaltinio puslapių, duodama 48 pavyzdžio/tikinio porų ir 6 448 patikrintų išvesties puslapių be jokių pasirinktų semantinių skirtumų. Visi 96 operacijų matavimai išlaikė teigiamas žalias skaitiklio reikšmes, suderintas su jų praneštomis sekundėmis, ir tos reikšmės sąmoningai nesujungiamos į tarpkompiliatorinę greičio lentelę, nes matrica yra funkcinis įrodymas, o ne kontroliuotas palyginimas. Įkėlimo ir įrašymo kelias taip pat neteigia, kad dekoduoja kiekvieną įmontuotą paveikslėlį, tikrina parašus, vykdo XFA arba sertifikuoja PDF/UA; jei reikia vertinti atvaizdavimo pralaidumą, o ne įkėlimo ir įrašymo kainą, lygiagretus puslapių atvaizdavimas ir gijų saugumas PDF Library for Delphi yra geresnis starto taškas
Praktinė išvada trumpa: saugokite žalius skaitiklius, kaitaliokite tvarką, statykite vartus startui, atmeskite triukšmingus išsibarstymus ir niekada nematuokite nepatikrintos išvesties. Tos taisyklės yra tai, kas leidžia PDF Library for Delphi sakyti „jokio išmatuojamo pokyčio“ taip pat drąsiai, kaip „greičiau“, o tas pats zondo šaltinis be pakeitimų kompiliuojasi Delphi ir FPC aplinkose Win32 ir Win64. Biblioteką, jos įkėlimo ir įrašymo API bei palaikomus kompiliatorius galite peržiūrėti PDF Library for Delphi produkto puslapyje