يعتبر معظم المطورين أمرا مفروغا منه أن تحسين الأداء معقد ويتطلب الكثير من الخبرة والمعرفة. حسنًا ، لا يمكن القول أن هذا خطأ تمامًا. إن تحسين طلبك للحصول على الأداء الأمثل ليس مهمة سهلة. ومع ذلك ، هذا لا يعني أنه لا يمكنك فعل أي شيء إذا لم يكن لديك هذه المعرفة. فيما يلي 11 نصيحة سهلة المتابعة وأفضل الممارسات لمساعدتك في إنشاء تطبيق جيد الأداء.
معظم الاقتراحات هي لجافا. ولكن هناك العديد من الاقتراحات المستقلة عن اللغة ويمكن تطبيقها على جميع التطبيقات ولغات البرمجة. قبل مناقشة تقنيات ضبط الأداء خصيصًا لـ Java ، دعونا نلقي نظرة على النصائح العامة.
1. لا تحسن حتى تعلم أنه ضروري
ربما تكون هذه واحدة من أهم نصائح ضبط الأداء. يجب عليك اتباع أفضل الممارسات المشتركة ومحاولة تنفيذ حالات الاستخدام بكفاءة. ومع ذلك ، هذا لا يعني أنه يجب عليك استبدال أي مكتبة قياسية أو إنشاء تحسينات معقدة قبل أن تثبت ضرورية.
في معظم الحالات ، لن يستغرق التحسين السابق لأوانه الكثير من الوقت فحسب ، بل سيجعل الرمز صعبًا أيضًا في القراءة والصيانة. والأسوأ من ذلك ، أن هذه التحسينات لا تجلب عادة أي فوائد ، لأن ما تقضيه كثيرًا من الوقت في تحسينه هو الجزء غير الحرمني من التطبيق.
لذا ، كيف تثبت أنك تحتاج إلى تحسين شيء ما؟
أولاً ، تحتاج إلى تحديد مدى سرعة رمز التطبيق الخاص بك ، على سبيل المثال ، تحديد وقت استجابة أقصى لجميع مكالمات API ، أو تحديد عدد السجلات المراد استيرادها في نطاق زمني محدد. بمجرد الانتهاء من ذلك ، يمكنك قياس أجزاء التطبيق بطيئة للغاية. ثم ، دعونا نلقي نظرة على الخدعة الثانية.
2. استخدم المحلل للعثور على عنق الزجاجة الحقيقي
بعد اتباع الاقتراح الأول وقررت أن بعض أجزاء التطبيق تحتاج إلى تحسين ، ثم من أين تبدأ؟
يمكنك حل المشكلة بطريقتين:
تحقق من الكود الخاص بك وابدأ بالجزء الذي يبدو مشبوهًا أو تشعر بأنه قد يكون مشكلة.
أو استخدم المحلل واحصل على معلومات مفصلة حول سلوك وأداء كل جزء من الكود.
آمل ألا أحتاج إلى شرح سبب اتباع الطريقة الثانية دائمًا.
من الواضح أن النهج القائم على المحلل يتيح لك فهم تأثير أداء الكود بشكل أفضل وتمكينك من التركيز على الأجزاء الأكثر أهمية. إذا كنت قد استخدمت محللًا ، فيجب أن تتذكر مدى دهشتك لمعرفة أجزاء الكود التي تعاني من مشاكل في الأداء. لأكون صادقًا ، قادني التخمين الأول إلى الاتجاه الخاطئ أكثر من مرة.
3. قم بإنشاء مجموعة اختبار الأداء للتطبيق بأكمله
هذه نصيحة عالمية أخرى يمكن أن تساعدك على تجنب العديد من المشكلات غير المتوقعة التي تحدث غالبًا بعد نشر تحسينات الأداء على الإنتاج. يجب عليك دائمًا تحديد مجموعة اختبار الأداء التي تختبر التطبيق بالكامل وتشغيله قبل وبعد تحسين الأداء.
ستساعدك عمليات الاختبار الإضافية هذه على تحديد الآثار الجانبية الوظيفية والأداء للتغيير والتأكد من عدم وجود ضرر من التحديثات الجيدة. هذا مهم بشكل خاص إذا كنت تعمل على المكونات التي تستخدمها عدة أجزاء مختلفة من التطبيق ، مثل قواعد البيانات أو ذاكرة التخزين المؤقت.
4. الصفقة الأولى مع أكبر عنق الزجاجة
بعد إنشاء مجموعة اختبار وتحليل التطبيق باستخدام المحلل ، يمكنك سرد مجموعة من المشكلات التي تحتاج إلى معالجة لتحسين الأداء. هذا رائع ، لكنه لا يزال لا يجيب على السؤال عن المكان الذي يجب أن تبدأ فيه. يمكنك التركيز على حلول سريعة المفعول ، أو البدء مع أهم الأسئلة.
يمكن أن تكون مخططات السرعة السريعة جذابة في البداية لأنه يمكنك إظهار النتيجة الأولى بسرعة. لكن في بعض الأحيان ، قد تحتاج إلى إقناع أعضاء الفريق الآخرين أو الإدارة بأن تحليل الأداء يستحق ذلك - لأنه لا يوجد تأثير في الوقت الحالي.
لكن بشكل عام ، أوصي بالتعامل مع أهم مشكلات الأداء أولاً. سيوفر لك ذلك أكبر تحسينات في الأداء وقد لم يعد بحاجة إلى حل بعض هذه المشكلات لتلبية متطلبات الأداء.
نصائح ضبط الأداء الشائعة تنتهي هنا. دعونا نلقي نظرة فاحصة على بعض النصائح الخاصة بالجافا.
5. استخدم StringBuilder لتوصيل السلسلة برمجيًا
هناك العديد من الخيارات المختلفة لتوصيل السلاسل في Java. على سبيل المثال ، يمكنك استخدام Simple + أو + = ، وكذلك StringBuffer أو StringBuilder.
لذا ، ما هي الطريقة التي يجب أن تختارها؟
تعتمد الإجابة على الرمز الذي يربط السلسلة. إذا كنت تقوم بإضافة محتوى جديد إلى سلسلة برمجيًا ، على سبيل المثال في حلقة For ، فيجب عليك استخدام StringBuilder. إنه سهل الاستخدام ويوفر أداء أفضل من StringBuffer. ولكن تذكر أنه بالمقارنة مع StringBuffer ، فإن StringBuilder ليس آمنًا للمعلومات وقد لا يكون مناسبًا لجميع حالات الاستخدام.
تحتاج فقط إلى إنشاء إنشاء سلسلة جديدة من stringbuilder والاتصال بالطريقة الملحقة لإضافة جزء جديد إلى السلسلة. بعد إضافة جميع الأجزاء ، يمكنك استدعاء طريقة ToString () لاسترداد السلسلة المتصلة.
يظهر مقتطف الكود التالي مثالًا بسيطًا. أثناء كل تكرار ، تقوم هذه الحلقة بتحويل I إلى سلسلة وتضيفها إلى StringBuilder SB مع مساحة. لذلك ، في النهاية ، سوف يكتب هذا الرمز "هذا اختبار 1 2 3 4 5 6 7 8 9" في ملف السجل.
StringBuilder SB = New StringBuilder ("هذا اختبار") ؛ لـ (int i = 0 ؛ i <10 ؛ i ++) {sb.append (i) ؛ sb.append ("") ؛} log.info (sb.toString ()) ؛كما ترون في مقتطف الكود ، يمكنك توفير العنصر الأول من السلسلة إلى المُنشئ. سيؤدي ذلك إلى إنشاء stringBuilder جديد يحتوي على السلسلة المقدمة و 16 حرفًا إضافيًا. عند إضافة المزيد من الأحرف إلى StringBuilder ، سيزيد JVM بشكل ديناميكي من حجم StringBuilder.
إذا كنت تعرف بالفعل عدد الأحرف التي ستحتويها سلسلتك ، فيمكنك توفير هذا الرقم لمشاركات مختلفة لإنشاء إنشاء StringBuilder بسعة محددة. هذا يعمل على تحسين الكفاءة لأنه لا يتطلب التوسع الديناميكي في قدرته.
6. استخدم + لتسلسل السلسلة في بيان
عندما تقوم بتنفيذ تطبيقك الأول في Java ، ربما أخبرك أحدهم أنه يجب ألا تستخدم + للاتصال بـ String. إذا كنت تتسلسل سلاسل في منطق التطبيق ، فهذا صحيح. السلاسل غير قابلة للتغيير ، ويتم تخزين نتائج تسلسل كل سلسلة في كائن سلسلة جديد. يتطلب ذلك ذاكرة إضافية وسيؤدي إلى إبطاء التطبيق الخاص بك ، خاصة إذا قمت بتسلسل سلاسل متعددة داخل حلقة.
في هذه الحالات ، يجب أن تتبع النصيحة 5 واستخدام StringBuilder.
ولكن إذا قمت بتقسيم السلسلة للتو إلى خطوط متعددة لتحسين قابلية قراءة الكود الخاص بك ، فهذا مختلف.
Query Q = Em.Createquery ("Select A.ID ، A.FirstName ، A.LastName"
+ "من المؤلف"
+ "حيث a.id =: id") ؛
في هذه الحالات ، يجب عليك استخدام Simple + لتسلسل السلسلة الخاصة بك. يعمل برنامج التحويل البرمجي Java على تحسين هذا ويقوم بالاتصالات في وقت الترجمة. لذلك ، في وقت التشغيل ، لن يستخدم التعليمات البرمجية الخاصة بك سوى سلسلة واحدة ولا يوجد أي اتصال مطلوب.
7. استخدم البدائية قدر الإمكان
هناك طريقة أخرى سهلة وسريعة لتجنب النفقات العامة وتحسين أداء التطبيق وهي استخدام النوع الأساسي بدلاً من فئة التفاف. لذلك ، من الأفضل استخدام int بدلاً من عدد صحيح ومضاعف بدلاً من ضعف. يتيح هذا لـ JVM تخزين القيم على المكدس بدلاً من الكومة لتقليل استهلاك الذاكرة وجعل معالجة أكثر كفاءة.
8. حاول تجنب BigInteger و BigDecimal
نظرًا لأننا نناقش أنواع البيانات ، فلنلقي نظرة سريعة على BigInteger و BigDecimal. على وجه الخصوص ، هذا الأخير يحظى بشعبية لدقته. ولكن هناك سعر.
يتطلب BigInteger و BigDecimal ذاكرة أكثر من البسيطة الطويلة أو المزدوجة وسيؤدي إلى إبطاء جميع الحسابات بشكل كبير. لذلك ، إذا كنت بحاجة إلى دقة إضافية ، أو ستتجاوز الأرقام المدى الطويل ، فمن الأفضل التفكير مرتين قبل القيام بذلك. ربما تكون هذه هي الطريقة الوحيدة التي تحتاج إلى تغييرها لحل مشاكل الأداء ، خاصة عند تنفيذ الخوارزميات الرياضية.
9. تحقق أولاً من مستوى السجل الحالي
يجب أن يكون هذا الاقتراح واضحًا ، لكن لسوء الحظ ، يتجاهل العديد من المبرمجين في الغالب عند كتابة التعليمات البرمجية. قبل إنشاء رسالة تصحيح ، يجب عليك دائمًا التحقق من مستوى السجل الحالي أولاً. خلاف ذلك ، يمكنك إنشاء سلسلة رسائل سجل سيتم تجاهلها لاحقًا.
فيما يلي مثالان سلبيان.
// لا تفعل thislog.debug ("user [" + username + "] تسمى الطريقة x مع [" + i + "]") ؛ // أو thislog.debug (string.format ("user [٪ s] يسمى الطريقة x مع [٪ d] ، اسم المستخدم ، i)) ؛في كلتا الحالتين ، ستقوم بتنفيذ جميع الخطوات اللازمة لإنشاء رسالة سجل دون معرفة ما إذا كان إطار السجل سيستخدم رسالة السجل. لذلك ، من الأفضل التحقق من مستوى السجل الحالي قبل إنشاء رسالة تصحيح.
// do thisif (log.isdebugenabled ()) {log.debug ("user [" + username + "] تسمى الطريقة x مع [" + i + "]") ؛}10. استخدم apache commons stringutils.replace بدلاً من string.replace
بشكل عام ، تعمل طريقة string.replace بشكل جيد وفعالة للغاية ، خاصة عند استخدام Java 9. ومع ذلك ، إذا كان تطبيقك يتطلب الكثير من عمليات الاستبدال ولم يتم تحديثه إلى أحدث إصدار من Java ، فلا يزال من الضروري إيجاد بدائل أسرع وأكثر كفاءة.
هناك إجابة بديلة على طريقة apache Commons Lang's StringUtils. كما تم وصف Lukas Eder في منشور حديث للمدونة ، فإن طريقة stringutils.replace أعلى بكثير من طريقة string.replace من Java 8.
ويتطلب فقط تغييرات طفيفة. وهذا يعني ، إضافة تبعيات Maven لمشروع Apache Commons Lang إلى Application pom.xml ، واستبدل جميع المكالمات إلى طريقة string.replace باستخدام طريقة stringutils.replace.
// استبدل thistest.replace ("Test" ، "اختبار بسيط") ؛ // مع ThisStringUtils.replace (اختبار ، "اختبار" ، "اختبار بسيط") ؛11. ذاكرة التخزين المؤقت باهظة الثمن ، مثل اتصالات قاعدة البيانات
يعتبر التخزين المؤقت حلاً شائعًا لتجنب التنفيذ المتكرر للمقتطفات الباهظة الثمن أو الشائعة. الفكرة العامة بسيطة: من أرخص إعادة استخدام هذه الموارد من إنشاء موارد جديدة مرارًا وتكرارًا.
مثال نموذجي هو اتصال قاعدة البيانات في تجمع ذاكرة التخزين المؤقت. تستغرق التوصيلات الجديدة وقتًا لإنشاءها ، والتي يمكن تجنبها إذا قمت بإعادة استخدام الاتصالات الحالية.
يمكنك أيضًا العثور على أمثلة أخرى في لغة جافا نفسها. على سبيل المثال ، فإن طريقة القيمة الخاصة بتخزينات CACHER من فئة عدد صحيح بين -128 و 127. قد تقول إن إنشاء عدد صحيح جديد ليس باهظ الثمن ، ولكن نظرًا لأنه يتم استخدامه غالبًا ، فإن التخزين المؤقت للقيم الأكثر استخدامًا يمكن أن يوفر أيضًا مزايا الأداء.
ومع ذلك ، عندما تفكر في التخزين المؤقت ، تذكر أن تطبيقات ذاكرة التخزين المؤقت يمكن أن تتحمل النفقات العامة أيضًا. تحتاج إلى إنفاق ذاكرة إضافية لتخزين الموارد القابلة لإعادة الاستخدام ، لذلك قد تحتاج إلى إدارة ذاكرة التخزين المؤقت لجعل الموارد متاحة ، وكذلك حذف الموارد القديمة.
لذلك ، قبل البدء في تخزين أي موارد ، تأكد من أن تنفيذ ذاكرة التخزين المؤقت يستحق ذلك ، أي عليك استخدامها بما فيه الكفاية.
لخص
كما ترون ، في بعض الأحيان لا يتطلب الأمر الكثير من العمل لتحسين أداء التطبيق الخاص بك. تتطلب معظم الاقتراحات الواردة في هذه المقالة مجرد جهد صغير لتطبيقها على الكود الخاص بك.
لكن الشيء الأكثر أهمية هو الحيل التي لا تتعلق بلغة البرمجة هي:
لا تحسن استخدام المحللين للعثور على اختناقات حقيقية قبل أن تعرف أنه ضروري. أول صفقة مع أكبر اختناقات.
ما سبق هو كل المحتوى المشترك في هذه المقالة حول تقنيات ضبط أداء Java البسيطة للغاية وسهلة الفهم. آمل أن يكون ذلك مفيدًا للجميع. يمكن للأصدقاء المهتمين الاستمرار في الرجوع إلى هذا الموقع:
تقوم Java بتنفيذ رمز مفصل لمشاركة وظائف WeChat Public Platform Wechat Moments
التحليل المقارن لحالات الأداء من التسلسل الأصلي Java والتسلسل Kryo
استكشاف ما إذا كانت الفئة الفرعية لبرمجة Java يمكنها إعادة كتابة الطريقة الثابتة للفئة الأصل
إذا كانت هناك أي أوجه قصور ، فيرجى ترك رسالة لإشارةها. شكرا لك يا أصدقائك لدعمكم لهذا الموقع!