أداء التطبيق

[مؤرشف] آخر تحديث بواسطة Joe Schaefer في Sat, 10 Jan 2026    مصدر
 

يقع العديد من المطورين في فخ التفكير في تحسين الأداء هو جعل كل سطر من التعليمات البرمجية أكثر كفاءة قدر الإمكان.، أو اختيار كتابة التطبيق بأكمله بأسرع لغة برمجة يمكنهم العثور عليها.

إنها’في الواقع العكس. تبدأ بالقيود المعمارية للتطبيق، وتستخدمها للتنقل لأسفل إلى الملاحظة “أبطأ” جزء من البرنامج. هذا الجزء’s التنفيذ يوجه كل اختيارات الأداء الأخرى التي تحتاج إلى اتخاذها. أي شيء’ليست بطيئة مثل هذا الجزء، لا تحتاج إلى مزيد من التحسين. بدلا من ذلك، التركيز على التعبير البشري وبساطة ووضوح التنفيذ، للقراء غير الخبراء على SSDLC من البرنامج، لبقية البرنامج الخاص بك’رمز s.

يمكنك التكرار في هذا الدليل، لكنني’لم أكن بحاجة إلى تجاوز 3 تكرارات في مسيرتي المهنية.

لذلك المضي قدما واستخدام لغة برمجة أنيقة مثل Python3 أو جافاسكرِبت/سكريبت، ودع خبراء الموضوع (SME) هناك في العالم مفتوح المصدر يمنحك قوة جيم/C ++ روابط محلية لاحتياجاتك الخاصة. لا شيء تفعله لمنطق الأعمال يحتاج إلى سرعة أكبر من أي لغة برمجة ديناميكية يمكن أن تعطيك جاهزة.

حتى برنامج bash النصي الخالي من التبعية هو حل عملي للعديد من المهام الأساسية. هنا’واحد كتبته لشركة الواقع المعزز قفزة سحرية قبل سنوات، لتحل محل خرقاء OpenGrok خدمة مع شيء يستفيد من التوازي متعدد المعالجات مع xargs - P، ويدعم بر بحث بكل بساطة إيماك/فيم الروابط.

https://github.com/joesuf4/home/blob/wsl/bin/pffxg.sh

هذا النص هو ترتيب من الحجم أسرع من المعتاد المشتبه بهم على GitHub، والتي كانت كلها مكتوبة في ثابت، تجميع لغات البرمجة. ولكن من خلال تحديد الاختناقات الدقيقة في يندفع (حلقة ذات حجم كبير) شوكة + تنفيذ المكالمات في الوسط)، واستخدام لباس سباحة بدلاً من ذلك، تحصل على سكريبت يشبه هذا البرنامج كثيرًا، مع تنفيذ الخوارزمية الأساسية في 10 أسطر من قذيفة.

إنها’يستخدم أيضًا مجتمع المصدر المفتوح SME‘بطريقة ذكية، بدلا من الطريقة الأخرى “grep متكرر مرشح” تم تطبيقه على GitHub. بدلا من اعتماد والحفاظ على بلدي (مترابطة) تنفيذ وجد, لباس سباحة، و دهن، أقوم فقط بإعادة استخدام الملفات التنفيذية المثبتة مسبقًا الأخرى SME‘لقد كانت مثالية على مدى عقود **كما هو **، وتستخدم في المقام الأول قذيفة بنيتنس للبقية. لا’لا تحتاج إلى إتقان عمليات التنفيذ الخاصة بهم، فقط إعادة استخدام CLIث. لا’حتى تريد إتقانهم، أن’(وَإِنَّ اللَّهَ عَزَّ وَجَلَّ) . تهم دلتا الأداء فقط عندما تكون عدة ثوان أو أكثر، بالنظر إلى التطبيق’حالات الاستخدام المتوقعة (البشرية).

ما تبقى من البرنامج النصي يستفيد في المقام الأول من البنايات قذيفة باش، والتي يتم تنفيذها في نقية جيم.

لرؤية عكس ذلك، حيث يتم كل شيء داخل الشركة، محسّن بالكامل، ولا يزال بإمكانه’t التفوق على هذا البرنامج النصي مع خيارات البحث الافتراضية، ولا يوجد نظام التخزين المؤقت المتاحة، وهنا مثال جيد https://github.com/BurntSushi/ripgrep

فقط لسحب أول #performance #benchmark من تلك الصفحة، وتوسيعه من حجم شجرة عينة لعبة (مصادر نواة لينكس)، إلى شجرة غير متجانسة’ss 23GB: (أفضل يعمل بعد 3 تكرارات ؛ لغة=en_US.UTF-8).

    % du -sh .
    23G .
    % time rg -uuniw '[A-Z]+_SUSPEND' | wc -l
    6259
    rg -uuniw '[A-Z]+_SUSPEND' 9.46s user 16.08s system 261% cpu 9.759 total
    wc -l 0.00s user 0.07s system 0% cpu 9.759 total
    % time pffxg.sh -- -wnE '[A-Z]+_SUSPEND' | wc -l
    5855
    pffxg.sh -- -wnE '[A-Z]+_SUSPEND' 16.66s user 2.68s system 429% cpu 4.501 total
    wc -l 0.00s user 0.00s system 0% cpu 4.501 total

إنها’s سخيفة جدا ل microoptimize شيء أن’ترتبط ارتباطا عميقا بحالة النواة’الذاكرة المخبئية لنظام الملفات للبحث الخاص بك. ويهيمن الاختلاف في توقيتات الأداء من خلال سرعة الوصول إلى مجموعة من الملفات’ المحتويات، وهو ترتيب من الحجم أكثر ملاءمة من أي عامل آخر للنتائج النهائية. أن تكون على NVMe يساعد، ولكن لا شيء في هذا الفضاء يدق الذاكرة نفسها.

هذا’لماذا وجود ذاكرة مخبئية مضغوطة في الذاكرة لمجموعة كبيرة من الملفات، سيعمل على تثبيت توقيتات الأداء. من المستغرب أن لا أحد يعتقد أن هذا مهم بما يكفي لدعمه.

خذ #performance #benchmark الثاني من تلك الصفحة، وقم بتوسيعه كما كان من قبل (نفس 23GB الشجرة:

    % time rg -tc -uuuiwn '[A-Z]+_SUSPEND' | wc -l
    5629
    rg -tc -uuuiwn '[A-Z]+_SUSPEND' 3.51s user 1.71s system 1141% cpu 0.457 total
    wc -l 0.00s user 0.05s system 11% cpu 0.457 total
    % time LANG=C pffxg.sh --cache /tmp/pffxg-$USER --workers 32 --cc -- -wE '[A-Z]+_SUSPEND' | wc -l
    5628
    LANG=C pffxg.sh --cache /tmp/pffxg-$USER --workers 32 --cc -- -wE  3.14s user 0.88s system 1055% cpu 0.381 total
    wc -l 0.00s user 0.00s system 0% cpu 0.381 total

تم ضبطه pffxg.sh لا يزال أسرع، على الرغم من كل العمل وضعت في microoptimizing ripgrep لهذا جيم-بحث الملف.

طريقة استخدام هذا البرنامج النصي مع AOSP كان جدولة a استعادة المزامنة و اللاحقة pffxg.sh lz4-الذاكرة المخبئية المضغوطة من البذور إلىtmpfs ركض كل صباح قبل العمل كرونجاب)، مع PFFXG_CACHE=... تعيين في ~/.pffxg.conf ملف. أي: pffxg.sh الاستدعاءات التي قمت بتشغيلها طوال يوم العمل ستستخدم الذاكرة المخبئية المضغوطة في tmpfsبغض النظر عن حالة النواة’كانت ذاكرة التخزين المؤقت لنظام الملفات في ذلك الوقت.

.25M موقع بين ناضجة و يوجريب. 632 LOC ل pffxg.sh. سخيف.

لأنه’s مثل برنامج قذيفة صغيرة، pffxg.sh يمكن أن تعطيك السنانير قوية في الداخل مع ما يقرب من صفر الجهد. حتى دهن الأمر نفسه قابل للتخصيص: أي أمر تحتاج إلى تشغيله على مجموعة مختارة من الملفات، والتي يمكن أن تقبل قائمة بأسماء الملفات الملحقة بنهاية حججها، هي لعبة عادلة. هنا’s a “إجمالي عدد السطور في MiLOC“ ممارسة على لينكس نواة جيت ريبو:

    % time find *-type f | xargs wc -l | awk '{ $2 == "total" {a+=$1} END {print a/1024**2}'
    28.451
    find *-type f 0.00s user 0.06s system 2% cpu 2.733 total
    xargs wc -l 0.53s user 1.02s system 54% cpu 2.853 total
    awk '$2 == "total" {a+=$1} END {print a/1024**2}' 0.23s user 0.59s system 28% cpu 2.853 total

% time pffxg.sh --workers 8 --cmd wc --all -- -l | awk '{$2 == "total" {a+=$1} END {print a/1024**2}'
    28.4506
    pffxg.sh --workers 8 --cmd wc --all -- -l 0.92s user 0.66s system 826% cpu 0.192 total
    awk '$2 == "total" {a+=$1} END {print a/1024**2}' 0.02s user 0.00s system 11% cpu 0.192 total

ناضجة الإصدار:

    % time rg -c \$ | awk -F : '{a+=$2} END {print a/1024**2}'
    28.4284
    rg -c \$ 2.12s user 2.19s system 276% cpu 1.564 total
    awk -F : '{a+=$2} END {print a/1024**2}' 0.58s user 0.45s system 66% cpu 1.564 total

هنا يقتصر على جيم-files (نفس شجرة لينكس):

    % time pffxg.sh --workers 8 --cc --cmd wc -- -l | awk '$2 == "total" {a+=$1} END {print a/1024**2}'
    25.3935
    pffxg.sh --workers 8 --cc --cmd wc -- -l 0.76s user 0.54s system 734% cpu 0.177 total
    awk '$2 == "total" {a+=$1} END {print a/1024**2}' 0.02s user 0.00s system 9% cpu 0.177 total

و ناضجة الإصدار:

    % time rg -tc -c \$ | awk -F : '{a+=$2} END {print a/1024**2}'
    25.3844
    rg -tc -c \$ 3.49s user 1.54s system 441% cpu 1.140 total
    awk -F : '{a+=$2} END {print a/1024**2}' 0.38s user 0.38s system 66% cpu 1.140 total

أداء التطبيق الحقيقي يأتي من التوازن والمرونة وتقنيات البرمجة الوظيفية ؛ لا يأتي من التثبيت على تكتيكات التحسين الدقيق الضرورية بلغات برمجة ثابتة ومجمعة تحمل العمل معها من منظور التوازن والمرونة. تعد هذه اللغات المفرطة في الكتابة والضرورية أهدافًا كبيرة لنطاقات المشكلات المحددة للغاية، ولكنها فظيعة لأداء التطبيقات على مستوى المنظومة.

pffxg.sh ليس منتجًا، وهذا ليس عرضًا للمبيعات. إنها’مثال** يوضح وجهة نظري بطريقة مثيرة للغاية. إذا كنت على دراية بالتاريخ الطويل للحلول المرشحة المتكررة على GitHub، فكلها مبنية على فكرة أن المشكلة مع آندي ليستر’أصلي بيرل تنفيذ حَمَّام، هل كانت مكتوبة في بيرل. المشكلة الحقيقية الوحيدة من وجهة نظر الأداء هي أن بيرل كتبه آندي، الذي لم’يبدو أن لديها أي مهارة لمفاهيم أداء الأنظمة (مثل الزراعة خارج وجد عمل الموازاة مع مُصمم لغرض معين جيم ثنائي)، ولكن بدلاً من ذلك استهدف قابلية النقل الكسولة من خلال محاولة التقاط التعليمة البرمجية بأكملها على هيئة Pure ذات تسلسل عمليات واحد بيرل الغرابة

قد تزهر ألف زهرة، بغض النظر عن سخيفة تبدو!