قياس أداء نزيه لتحميل وحفظ الملفات في PDF Library for Delphi يقيس زمن LoadFromFile و SaveToFile بـ QueryPerformanceCounter، ويحفظ النبضات الخام وتردد العدّاد، ويشغّل الأساس والمرشح في أزواج A/B و B/A و A/B متناوبة، ويرفض البدء ما دام حمل المعالج فوق 25%، ويرفض أي نتيجة تجاوز اتساع مداها إلى وسيطها 15%، ويرمي كل قياس كان ملف PDF المحفوظ فيه يفشل في التحقق البنيوي أو العرضي أو الدلالي. تلك القائمة تبدو بيروقراطية حتى أول مرة يتبخر فيها ادعاء «أسرع بـ 20%» عند إعادة التشغيل. وما يلي هو كيف وصلت أداة التفحص المخصصة للمخزون ومشغّل المقارنة لديها إلى هناك، بما في ذلك التشغيلة التي كانت الآلة فيها مشغولة عن قياس أي شيء أصلاً فقالت المنظومة ذلك بصدق
لماذا يبلّغ مقياس أداء PDF في Delphi عن صفر ثانية؟
يبلّغ مقياس تحميل PDF عن صفر ثانية حين تكون نبضات ساعته أخشن من العملية التي يقيسها، و GetTickCount64 هي ذلك النوع من الساعات بالضبط: تعيد ميلي ثانية، لكنها على Windows لا تتقدم إلا حين تنطلق مقاطعة مؤقت النظام، وعادة كل 15.6 ms. استخدمتها نسخة FPC من استعراض قياس الملفات الضخمة في PDF Library for Delphi لأن TStopwatch غير متاحة في تلك السلسلة الأدواتية، وهي تسجل الزمن المنقضي بثلاث خانات عشرية. تحميل رسم CAD صغير أو مستند موسوم قصير ينتهي داخل خطوة مؤقت واحدة بوفرة، فكان الاستعراض أحياناً يطبع 0.000 لتحميل قام بعمل حقيقي بلا شك
function ElapsedSeconds(StartTick: QWord): Double;
begin
Result:= (GetTickCount64- StartTick)/ 1000.0;
end;
// داخل حلقة العملية
Lib:= TPDFlib.Create;
try
Lib.OnProgress:= Reporter.Progress;
Started:= GetTickCount64;
LoadCode:= Lib.LoadFromFile(InputFile, Password);
...
الصفر أسوأ من رقم غير دقيق، لأن كل مقارنة تبنيها عليه تقسم عليه. يعامل مشغّل المقارنة المزدوجة أي ذراع حدّها الأدنى صفراً بوصفها غير حاسمة بسبب «مدة صفرية تمنع نسبة ذات معنى»، وذلك رفض صائب، لكنه يعني أيضاً أن قياسات الاستعراض تركت فجوة قياس بالضبط حيث تسكن الملفات القصيرة. والاستعراض نفسه يركّب كذلك نداء OnProgress الرجعي، فقياساته تحمل كلفة النداء التي لا ينبغي لقياس تحميل/حفظ نظيف أن يحملها، وأرقام الاستعراض المؤرشفة لا تتبادل مع أي شيء قيس لاحقاً
قياس زمن LoadFromFile و SaveToFile بـ QueryPerformanceCounter
تفحص Tests/CorpusLoadSave.dpr، أداة سطر الأوامر المخصصة، عمليتين لكل ملف مدخل بـ QueryPerformanceCounter: LoadFromFile مع قراءة PageCount، و LoadFromFile مع PageCount مع SaveToFile. تحصل كل عملية على نسخة TPDFlib جديدة وبلا نداء تقدم، ويجلس باني النسخة وهادمها خارج المنطقة الموقوتة، كما تجلس كتابة CSV وكل تحقق من المخرجات. ويُقرأ العدّاد قبل التحميل مباشرة وبعد آخر استدعاء مكتبة مباشرة، ولا يُجلب LastErrorCode إلا بعد القراءة الثانية
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');
تكتب الأداة عدد النبضات الخام وتردد العدّاد بجوار الثواني المشتقة، منسقة بتسع خانات عشرية وفاصلة عشرية ثابتة .، فيستطيع أي أحد إعادة حساب الخارج القسمة من ملف CSV بدل الثقة به. على بنية FPC Win64 حُمّل نموذج CAD في 8,888 نبضة عند 10,000,000 نبضة في الثانية، مسجلاً 0.000888800 ثانية — وهي مشاهدة كان المؤقت القديم سيقرّبها إلى صفر. ترفض الأداة عمداً بتر القيم القصيرة أو استبدال مدة دنيا أو خصم كلفة مؤقت مقدّرة، وهي تكتب الصفين كليهما بكود خروج غير صفري حتى حين يفشل استدعاء مكتبة. لكن تسع خانات ليست دقة: الدقة المسجلة الزائدة لا تقول شيئاً عن قابلية التكرار، والمشاهدات الضجيجية أو الصفرية لا بد أن تُرفض في اتجاه المصب
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));
ماذا يجعل مقارنة قياس تحميل/حفظ PDF جديرة بالثقة؟
مقارنة القياس بين بنيتين من PDF Library for Delphi لا تكون جديرة بالثقة إلا حين يُضبط ترتيب البدء وشروط البدء والاتساع كلها ويُسجل، لذلك يجدول مشغّل المقارنة ثلاثة أزواج على الأقل بترتيب A/B و B/A و A/B. تشغيل الأساس أولاً دائماً يمنح المرشح في صمت مخزن ملفات أدفأ وحالة حرارية مختلفة؛ وتناوب الترتيب ينشر ذلك التحيز على الذراعين بدل إطماره في واحدة. قبل كل ذراع يبصم المشغّل ملف المدخل كاملاً بـ SHA-256، فيتحقق بذلك أن شيئاً لم يتغير ويقرأ البايتات نفسها مسبقاً لأي ذراع، ويعيد بصم الملفين التنفيذيين وأدوات التحقق بعد كل تشغيلة حتى لا يتسلل ثنائي معاد بناؤه إلى منتصف سلسلة
ثم يأخذ المشغّل عينات من استغلال المعالج على مستوى الآلة مرة كل ثانية ولا يبدأ الذراع إلا حين تهبط عينة إلى 25% أو دونها، منتظراً 30 ثانية على الأكثر قبل تسجيل المحاولة مرفوضة. تلك البوابة تضبط شرط البدء ولا شيء غيره: فهي لا تعزل الآلة أثناء التشغيل، وحالة الطاقة والتخفيض الحراري والعمل في الخلفية والتخزين المؤقت لنظام التشغيل ما زالوا قادرين على تحريك الأرقام. لذا فالمرشح الثاني إحصائي بالمعنى الأبسط. عن كل عملية يحسب المشغّل المدة على الوسيط للذراع الأساس ولذراع المرشح وللتوزيع بين النسب المزدوجة مرشح/أساس، وإذا تجاوز أي من الثلاثة 0.15 وُسمت النتيجة ضجيجية بدل أن تُبلّغ نتيجة
لماذا يثبت ضبط الثنائي نفسه قابلية التكرار لا السرعة؟
ضبط الثنائي نفسه يشغّل ملفات تنفيذية متطابقة أساساً ومرشحاً، فالنسبة القريبة من 1.0 لا تثبت إلا أن منظومة القياس تكرر نفسها؛ ولا يمكنها أبداً أن تبيّن أن تنفيذاً ما صار أسرع. استخدم أول ضبط صارم في 2026-09-21 أداة FPC Win64 عالية الدقة على دليل موسوم معتمد من 70 صفحة، ورُفضت البدءات الست كلها لأن عينات المعالج تراوحت بين 26.5% و 93.8%. احتوى التقرير على إخفاقات بلا مجاميع، وهي بالضبط النتيجة التي تريدها حين تكون الآلة مشغولة. وأعادت محاولة في اليوم نفسه بمدخلات متطابقة بايتياً وبالملف التنفيذي نفسه للأداة وبعتبات لم تتغير قبول البدءات الست كلها خلال 3 ثوانٍ؛ وهبط كل اتساع مدى/وسيط بين 0.019 و 0.054، وكانت أوساط النسب 1.0084 لـ LoadFromFile و 0.9872 لـ LoadFromFile + SaveToFile
ذلك الزوج من الأرقام يثبت نافذة مشاهدة مؤهلة ولا شيء غير ذلك. حين يختلف الثنائيان تُوسم التشغيلة المستقرة مقارنة وصفية، مع تنبيه صريح بأن النسب مشاهدات لا دلالة إحصائية ولا ادعاء تسريع. ويقف الانضباط أهم ما يكون حين تتحقق من تحسينات موجهة مثل التي وصفها تنميف PDF Library for Delphi واستبدال المسارات الساخنة بفهارس تجزئة: المنميف يقول لك أين يذهب الوقت، لكن التشغيلة المزدوجة المضبوطة على مستندات حقيقية وحدها تقول لك هل نجا التغيير من الاحتكاك بخط الأنابيب كله. وحد آخر يستحق أن يقال بصوت عال — normal-save يشمل التحميل، ومجموع العمل الأقصى الذي يسجله المشغّل على مستوى العملية، فلا شيء منه ذاكرة تنسب إلى الحفظ وحده
ثلاث بوابات مخرجات ومصفوفة أربعة مترجمات
لا يُحتسب أي قياس من PDF Library for Delphi إلا إذا نجح الملف الذي أنتجته في ثلاث بوابات مستقلة، لأن الحفظ الذي يكتب PDF فاسداً بسرعة ليس حفظاً أسرع. يفحص المقياس أولاً أن العمليتين أعادتا 1 وبلّغتا عدد الصفحات المعتمد، ثم يتحقق من ملف PDF المحفوظ الواحد بهذا الترتيب:
- البنية: يجب أن يمر فاحص PDF مستقل على الملف المحفوظ بلا أخطاء ولا تحذيرات
- العرض: تُعرض كل صفحة في حالتها الافتراضية، ويجب أن تطابق مجموعة SHA-256 لصور الصفحات عرض المصدر المعتمد المرجعي تطابقاً تاماً
- الدلالات غير البصرية: تغطي مقارنة دلالية منفصلة ضد المصدر خصائص مختارة لا تستطيع البكسلات إظهارها، بما فيها بنى المحتوى الاختياري وبنى القياس داخل نطاقها الموثق
وبوضع تلك البوابات، جرت مصفوفة المخزون المحلي الكاملة الأداة على FPC Win32 و FPC Win64 و Delphi Win32 و Delphi Win64 على 12 ملف PDF معتمداً بـ 1,612 صفحة مصدر، فأعطت 48 زوج عينة/هدف و 6,448 صفحة ناتج متحققاً منها بلا فروق دلالية مختارة. واحتفظت كل قياسات العمليات الـ 96 بقيم عدّاد خام موجبة متسقة مع ثوانيها المبلغة، وترُكت هذه القيم عمداً دون تجميع في جدول سرعة عبر المترجمات، لأن المصفوفة دليل وظيفي لا مقارنة مضبوطة. ومسار التحميل/الحفظ لا يدّعي أيضاً فك كل صورة مضمّنة ولا التحقق من التواقيع ولا تنفيذ XFA ولا اعتماد PDF/UA؛ وإن كنت تحتاج إلى الحكم على معدل نقل العرض لا كلفة التحميل/الحفظ، فقيود التزامن في عرض الصفحات المتوازي وسلامة الخيوط في PDF Library for Delphi هي نقطة البداية الأنسب
الخلاصة العملية قصيرة: احفظ العدادات الخام، وناوب الترتيب، وضع بوابة للبدء، وارفض الاتساعات الضجيجية، ولا توقت أبداً ناتجاً لم تتحقق منه. تلك القواعد هي ما يتيح لـ PDF Library for Delphi أن تقول «لا تغيير قابل للقياس» بثقة «أسرع» نفسها، ومصدر الأداة نفسه يُترجم دون تغيير على Delphi و FPC لـ Win32 و Win64. ويمكنك مراجعة المكتبة وواجهة التحميل/الحفظ فيها والمترجمات المدعومة على صفحة منتج PDF Library for Delphi