تحسين البرامج من خلال مواصفات رمز Java ، وتحسين استخدام الذاكرة ، ومنع تسرب الذاكرة
الموارد المتاحة للبرامج للاستخدام (الذاكرة ، وقت وحدة المعالجة المركزية ، عرض النطاق الترددي للشبكة ، وما إلى ذلك) محدودة. يتضمن التحسين عادةً جانبين: تقليل حجم الكود وتحسين كفاءة تشغيل الكود. تناقش هذه المقالة بشكل أساسي كيفية تحسين كفاءة الكود.
في برامج Java ، فإن معظم أسباب مشاكل الأداء ليست بلغة Java ، ولكن في البرنامج نفسه. من المهم للغاية تطوير عادات كتابة التعليمات البرمجية الجيدة ، مثل تطبيق Java.Lang.String Class و Java.Util.Vector بشكل صحيح وذكاء ، والتي يمكن أن تحسن أداء البرنامج بشكل كبير. دعنا نحلل هذه المشكلة بالتفصيل أدناه.
1. حاول تحديد المعدل النهائي للصف.
في Java Core API ، هناك العديد من الأمثلة على تطبيق النهائي ، مثل java.lang.string. تحديد النهائي لفئة السلسلة يمنع الناس من الكتابة فوق طريقة الطول (). بالإضافة إلى ذلك ، إذا تم تحديد الفصل الدراسي على أنه نهائي ، فإن جميع أساليب تلك الفئة نهائية. سيبحث برنامج التحويل البرمجي Java عن فرص لتضمين جميع الأساليب النهائية (وهذا مرتبط بتنفيذ برنامج التحويل البرمجي المحدد). هذه الخطوة يمكن أن تحسن الأداء بمتوسط 50 ٪.
2. حاول إعادة استخدام الكائن.
خاصة عند استخدام كائنات السلسلة ، يتم استخدام StringBuffer بدلاً من ذلك عند حدوث سلسلة متسلقة. نظرًا لأن النظام لا يستغرق وقتًا لإنشاء كائنات فحسب ، فقد يستغرق الأمر أيضًا وقتًا لجمع هذه الكائنات ومعالجتها في المستقبل. لذلك ، سيكون لتوليد الكثير من الكائنات تأثير كبير على أداء البرنامج.
3、 尽量使用局部变量,调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。
يتم إنشاء متغيرات أخرى ، مثل المتغيرات الثابتة ، ومتغيرات المثيل ، وما إلى ذلك ، في الكومة وأبطأ. بالإضافة إلى ذلك ، قد يتم تحسين المتغيرات المحلية اعتمادًا على برنامج التحويل البرمجي/JVM المحدد. انظر "استخدم متغيرات المكدس عند الإمكان".
4. Do not repeat initialization of variables <br />By default, when calling the class constructor, Java will initialize the variable to a certain value: all objects are set to null, integer variables (byte, short, int, long) Set إلى 0 ، يتم تعيين المتغيرات العائمة والمتغيرات المزدوجة على 0.0 ، ويتم ضبط القيم المنطقية على خطأ. يجب ملاحظة ذلك بشكل خاص عندما يتم اشتقاق فئة من أخرى ، لأنه عندما يتم إنشاء كائن مع الكلمة الرئيسية الجديدة ، يتم تلقائيًا تلقائيًا
5、 在JAVA + ORACLE 的应用系统开发中, java中内嵌的SQL语句尽量使用大写的形式,以减轻ORACLE解析器的解析负担。
6.
نظرًا لأن تشغيل هذه الكائنات الكبيرة سيؤدي إلى إدراج نظام كبير ، وإذا لم تكن حذراً ، فسيؤدي ذلك إلى عواقب وخيمة.
7. نظرًا لأن JVM لها آلية GC الخاصة بها ، فإنها لا تتطلب الكثير من الاهتمام من مطوري البرامج ، مما يقلل من العبء على المطورين إلى حد ما ، ولكنه يغيب أيضًا عن الأخطار الخفية. في النظام .
شرط JVM لإعادة تدوير القمامة هو أنه لم يتم الرجوع إلى الكائن ؛ لذلك ، يوصى بتعيينه يدويًا على Null بعد استخدام الكائن.
8. عند استخدام آلية التزامن ، حاول استخدام مزامنة الطريقة بدلاً من مزامنة كتلة الكود.
9、 尽量减少对变量的重复计算<br />例如:for(int i = 0;i < list.size; i ++) {
...
}
يجب استبداله:
لـ (int i = 0 ، int len = list.size () ؛ i <len ؛ i ++) {
...
}
10. حاول تبني استراتيجية التحميل البطيئة ، أي ابدأ في الإنشاء عند الحاجة.
على سبيل المثال: String str = "aaa" ؛
إذا (i == 1) {
list.add (str) ؛
}
يجب استبداله:
إذا (i == 1) {
سلسلة str = "aaa" ؛
list.add (str) ؛
}
11. استخدم التشوهات بحذر
الشذوذ ليست جيدة للأداء. لرمي استثناء ، يجب أولاً إنشاء كائن جديد. يستدعي مُنشئ الواجهة القابلة للتسمية الطريقة المحلية (الأصلية) المسماة FillInstackTrace () ، وطريقة FillInstackTrace () تتحقق من المكدس وتجمع معلومات تتبع المكالمات. طالما تم طرح استثناء ، يجب على VM ضبط مكدس الاتصال لأنه يتم إنشاء كائن جديد أثناء المعالجة. لا يمكن استخدام الاستثناءات إلا لمعالجة الأخطاء ويجب عدم استخدامها للتحكم في تدفق البرنامج.
12. لا تستخدمه في حلقة:
يحاول {
} يمسك() {
}
يجب وضعه على الطبقة الخارجية.
13. استخدام StringBuffer:
تمثل StringBuffer سلسلة متغيرة وقابلة للكتابة.
هناك ثلاث طرق بناء:
StringBuffer () ؛
stringbuffer (int size) ؛
StringBuffer (String Str) ؛
المُنشئ المذكور هنا هو StringBuffer (طول int) ، وتشير المعلمة الطول إلى عدد الأحرف التي يمكن أن يحملها StringBuffer الحالي. يمكنك أيضًا استخدام طريقة EnsuReCapacity (الحد الأدنى للسعة) لضبط قدرتها بعد إنشاء كائن StringBuffer. أولاً ، دعنا نلقي نظرة على السلوك الافتراضي لـ StringBuffer ، ثم نجد طريقة أفضل لتحسين الأداء.
يحافظ StringBuffer على صفيف أحرف داخليًا. عندما يصل StringBuffer إلى الحد الأقصى لسعةه ، فإنه سيزيد من قدرته إلى 2 أضعاف السعة الحالية ويضيف 2 ، أي (2*القيمة القديمة +2). إذا كنت تستخدم القيمة الافتراضية ، بعد التهيئة ، ثم أضف أحرفًا إليها. إلى 70 (2*34+2). بغض النظر عن ذلك ، طالما أن StringBuffer يصل إلى الحد الأقصى لسعةه ، فإنه يتعين عليه إنشاء صفيف أحرف جديد ثم إعادة فحص الشخصيات القديمة والجديدة. لذلك ، ليس من الخطأ تحديد قيمة سعة التهيئة المعقولة لـ StringBuffer ، والتي ستجلب كسب الأداء الفوري. هذا يوضح دور ضبط عملية تهيئة StringBuffer. لذلك ، فإن استخدام قيمة السعة المناسبة لتهيئة StringBuffer هو دائمًا اقتراح مثالي.
14. استخدم Java Class Java.Util.vector بشكل معقول.
ببساطة ، المتجه هو مجموعة من مثيلات java.lang.object. يشبه المتجه صفيف ، ويمكن الوصول إلى عناصره من خلال فهرس في شكل عدد صحيح. ومع ذلك ، بعد إنشاء كائن من نوع المتجه ، يمكن توسيع حجم الكائن وتقليله وفقًا لإضافة أو حذف العناصر. يرجى النظر في المثال التالي لإضافة عناصر إلى المتجه:
كائن bj = كائن جديد () ؛
المتجه V = Vector (100000) ؛
لـ (int i = 0 ؛
i <100000 ؛
ما لم يكن هناك سبب كافٍ تمامًا لطلب إدراج عناصر جديدة أمام المتجه في كل مرة ، فإن الكود أعلاه سيء للأداء. في المُنشئ الافتراضي ، تكون سعة التخزين الأولية للمتجه 10 عناصر. تشبه فئة المتجهات فئة كائن StringBuffer. مقتطف الكود التالي هو أوامر حجم أسرع من المثال السابق:
كائن bj = كائن جديد () ؛
المتجه V = Vector (100000) ؛
لـ (int i = 0 ؛ i <100000 ؛ i ++) {v.add (obj) ؛
تنطبق نفس القاعدة على طريقة remove () لفئة المتجه. نظرًا لأن كل عنصر في المتجه لا يمكن أن يحتوي على "مساحة" بين كل عنصر ، فإن حذف أي عنصر آخر باستثناء العنصر الأخير يتسبب في العناصر بعد المضي قدمًا في العنصر المحذوف. وهذا يعني أن حذف العنصر الأخير من المتجه أقل عدة مرات "النفقات العامة" من حذف العنصر الأول.
على افتراض أننا نريد إزالة جميع العناصر من المتجه السابق ، يمكننا استخدام هذا الرمز:
لـ (int i = 0 ؛ i <100000 ؛ i ++)
{
v.remove (0) ؛
}
ومع ذلك ، مقارنة بالرمز التالي ، فإن الكود السابق هو أوامر حجم أبطأ:
لـ (int i = 0 ؛ i <100000 ؛ i ++)
{
v.remove (v.size ()-1) ؛
}
أفضل طريقة لحذف جميع العناصر من كائن V من ناقل النوع هي:
v.removeallelements () ؛
افترض أن الكائن V من نوع ناقل النوع يحتوي على السلسلة "Hello". فكر في الكود التالي ، الذي يزيل سلسلة "Hello" من هذا المتجه:
String s = "Hello" ؛
int i = v.indexof (s) ؛
if (i! = -1) v.remove (s) ؛
لا يبدو الرمز شيئًا خاطئًا ، لكنه سيء أيضًا للأداء. في هذا الرمز ، تبحث طريقة indexof () V بالتسلسل للعثور على السلسلة "Hello" ، وطريقة إزالة (S) تحتاج أيضًا إلى البحث بنفس الترتيب. النسخة المحسنة هي:
String s = "Hello" ؛
int i = v.indexof (s) ؛
إذا (i! = -1) v.remove (i) ؛
في هذا الإصدار ، نقدم مباشرة موضع الفهرس الدقيق للعنصر الذي يتم حذفه في طريقة REMOM () ، وبالتالي تجنب البحث الثاني. نسخة أفضل هي:
String s = "Hello" ؛
أخيرًا ، دعونا نلقي نظرة على مقتطف رمز حول فئة المتجه:
لـ (int i = 0 ؛ i ++ ؛ i <v.length)
إذا كانت V تحتوي على 100000 عنصر ، فسيقوم مقتطف الرمز هذا باستدعاء طريقة V.Size () 100000 مرة. على الرغم من أن طريقة الحجم هي طريقة بسيطة ، إلا أنها لا تزال تتطلب النفقات العامة لمكالمة الطريقة ، على الأقل يحتاج JVM إلى تكوين بيئة المكدس ومسحه. هنا ، لن يعدل الرمز الموجود داخل الحلقة حجم كائن نوع المتجه V بأي شكل من الأشكال ، لذلك من الأفضل إعادة كتابة الكود أعلاه في النموذج التالي:
حجم int = v.size () ؛
في حين أن هذا تغيير بسيط ، إلا أنه لا يزال يفوز بالأداء. بعد كل شيء ، كل دورة وحدة المعالجة المركزية ثمينة.
15. عند نسخ كمية كبيرة من البيانات ، استخدم الأمر System.ArrayCopy ().
16. إعادة تدوين الكود: تعزيز قابلية قراءة الكود .
على سبيل المثال:
Class Public Class ShopCart {Private List Carts ؛ ... public void add (عنصر كائن) {if (carts == null) {carts = new ArrayList () ؛} crts.add (item) ؛ (عربات. تحتوي على (عنصر)) {carts.remove (item) ؛}} القائمة العامة getCarts () {// return reath-list resturn . 17. قم بإنشاء مثيل فئة دون استخدام كلمات رئيسية جديدة
عند إنشاء مثيل لفئة مع الكلمة الرئيسية الجديدة ، سيتم استدعاء جميع المنشئين في سلسلة المنشئ تلقائيًا. ولكن إذا قام كائن بتطبيق الواجهة المستنسخة ، فيمكننا استدعاء طريقة Clone (). لا تسمي طريقة clone () أي منشئات فئة.
عند استخدام نمط التصميم ، إذا كنت تستخدم وضع المصنع لإنشاء كائن ، فمن السهل جدًا استخدام طريقة Clone () لإنشاء مثيل كائن جديد. على سبيل المثال ، ما يلي هو تطبيق نموذجي لنمط المصنع:
الائتمان الثابت العام getNewCredit () {
إرجاع الائتمان الجديد () ؛
}
يستخدم الرمز المحسن طريقة clone () على النحو التالي:
ائتمان ثابت خاص = ائتمان جديد () ؛
الائتمان الثابت العام getNewCredit () {
العائد (الائتمان) basecredit.clone () ؛
}
الفكرة أعلاه هي أيضا مفيدة جدا لمعالجة الصفيف.
18. الضرب والقسمة
النظر في الرمز التالي:
لـ (val = 0 ؛ val <100000 ؛ val += 5) {
Alterx = val * 8 ؛
}
يمكن أن يؤدي استبدال الضرب بعمليات التحول إلى تحسين الأداء بشكل كبير. هنا هو الكود المعدل:
لـ (val = 0 ؛ val <100000 ؛ val += 5) {
Alterx = val << 3 ؛
}
لم يعد الكود المعدل يتضاعف بمقدار 8 ، ولكنه يستخدم بدلاً من ذلك التحول الأيسر المكافئ يبلغ 3 بتات ، مع 1 بت لكل تحول يسار مكافئ للضرب بمقدار 2. تبعا لذلك ، فإن التحول الصحيح من قبل 1 بت العملية يعادل الانقسام على 2. تجدر الإشارة إلى أنه على الرغم من أن عملية التحول سريعة ، إلا أنها قد تجعل من الصعب فهم الكود ، لذلك من الأفضل إضافة بعض التعليقات.
19. أغلق جلسات عديمة الفائدة في صفحة JSP.
سوء الفهم الشائع هو أن يتم إنشاء الجلسة عندما يكون هناك وصول العميل. ، استخدم <> لإغلاقه. نظرًا لأن الجلسة تستهلك موارد الذاكرة ، إذا لم تكن تخطط لاستخدام الجلسة ، فيجب عليك إغلاقها في جميع JSPs.
بالنسبة للصفحات التي لا تحتاج إلى تتبع حالة الجلسة ، يمكن أن توفر الجلسات التي تم إنشاؤها تلقائيًا بعض الموارد. استخدم توجيه الصفحة التالية: <٪@ page session = "false" ٪>
20. JDBC و I/O
إذا احتاج التطبيق إلى الوصول إلى مجموعة بيانات واسعة النطاق ، فيجب عليك التفكير في استخدام استخراج الكتلة. بشكل افتراضي ، يستخرج JDBC 32 صفًا من البيانات في كل مرة. على سبيل المثال ، لنفترض أننا نريد اجتياز مجموعة سجلات من 5000 صف ، يجب على JDBC الاتصال بقاعدة البيانات 157 مرة قبل أن تتمكن من استخراج جميع البيانات. إذا تم تغيير حجم الكتلة إلى 512 ، فسيتم تخفيض عدد المكالمات إلى قاعدة البيانات إلى 10 مرات.
21. استخدام Servlet واستخدام الذاكرة <BR /> ينقذ العديد من المطورين كمية كبيرة من المعلومات إلى جلسات المستخدم في الإرادة. في بعض الأحيان ، لا يتم إعادة تدوير الأشياء المخزنة في الجلسة بواسطة آلية جمع القمامة في الوقت المناسب. من منظور الأداء ، يتمثل أحد الأعراض النموذجية في أن المستخدم يشعر أن النظام يتباطأ بشكل دوري ، لكن لا يمكن أن يعزى سبب أي مكون معين. إذا قمت بمراقبة مساحة كومة JVM ، فمن الواضح أنها تقلبات غير طبيعية لاستخدام الذاكرة.
هناك طريقتان رئيسيتان لحل هذا النوع من مشكلة الذاكرة. الطريقة الأولى هي تنفيذ واجهة HTTPSENESSBINDINGLISTENER في جميع الفاصوليا مع نطاق الجلسة. وبهذه الطريقة ، طالما تم تنفيذ طريقة ValueNbound () ، يمكن إطلاق الموارد التي تستخدمها الحبة بشكل صريح.
طريقة أخرى هي إبطال الجلسة في أقرب وقت ممكن. لدى معظم خوادم التطبيق خيار تعيين فاصل إبطال الجلسة. بالإضافة إلى ذلك ، يمكن أيضًا استدعاء طريقة SetMaxInactive () من الجلسة برمجيًا.
22. استخدم علامات المخزن المؤقت
أضافت بعض خوادم التطبيق وظيفة علامات عازلة لـ JSP. على سبيل المثال ، يدعم خادم WebLogic الخاص بـ BEA هذه الميزة منذ الإصدار 6.0 ، كما يدعم مشروع Symphony المفتوح هذه الميزة. يمكن لعلامات التخزين المؤقت JSP تخزين شظايا الصفحة والصفحة بأكملها. عند تنفيذ صفحة JSP ، إذا كانت جزء الهدف موجود بالفعل في المخزن المؤقت ، فلن يلزم تنفيذ الكود الذي يولد الشظية. يلتقط التخزين المؤقت على مستوى الصفحة طلبات عنوان URL المحدد ويؤثر على صفحة النتائج بأكملها. هذه الميزة مفيدة للغاية لسلال التسوق والكتالوجات والصفحات الرئيسية البوابة. بالنسبة لمثل هذه التطبيقات ، يمكن للتخزين المؤقت على مستوى الصفحة حفظ نتائج تنفيذ الصفحة للطلبات اللاحقة.
23. اختر آلية الاقتباس الصحيحة
في نظام تطبيقات JSP نموذجي ، غالبًا ما يتم استخراج أجزاء الرأس والتذييل ، ثم يتم تقديم الرأس والتذييل حسب الحاجة. حاليًا ، هناك طريقتان رئيسيتان لإدخال الموارد الخارجية في صفحات JSP: تشمل التوجيهات وتشمل الإجراءات.
قم بتضمين التوجيه: على سبيل المثال <٪@ include file = "copyright.html" ٪>. يقدم هذا التوجيه المورد المحدد في وقت الترجمة. قبل التجميع ، يتم دمج الصفحة التي تحتوي على توجيهات تضمين والمورد المحدد في ملف. يتم تحديد الموارد الخارجية المشار إليها في وقت الترجمة ، وهو أكثر كفاءة من تحديد الموارد في وقت التشغيل.
قم بتضمين الإجراء: على سبيل المثال <JSP: قم بتضمين page = "copyright.jsp" />. يقدم هذا الإجراء النتيجة التي تم إنشاؤها بعد تنفيذ الصفحة المحددة. نظرًا لأنه يكمل في وقت التشغيل ، فإن التحكم في نتائج الإخراج أكثر مرونة. ومع ذلك ، فمن غير الفعال من حيث التكلفة فقط أن يتضمن الإجراء عندما يتم تغيير المحتوى المقتبس بشكل متكرر ، أو عندما لا يمكن تحديد الصفحة المشار إليها قبل ظهور طلب الصفحة الرئيسية.
24. واضح لم يعد هناك حاجة إلى جلسات في الوقت المناسب
من أجل مسح الجلسات التي لم تعد نشطة ، تحتوي العديد من خوادم التطبيق على مهلة جلسة افتراضية ، عادة 30 دقيقة. عندما يحتاج خادم التطبيق إلى حفظ المزيد من الجلسات ، إذا كانت سعة الذاكرة غير كافية ، فإن نظام التشغيل سيقوم بنقل جزء من بيانات الذاكرة إلى القرص. تخزين إلى القرص وقد يرمي استثناء "خارج الذاكرة". في الأنظمة على نطاق واسع ، جلسات التسلسل باهظة الثمن. عندما لم تعد هناك حاجة للجلسة ، يجب استدعاء طريقة httpsession.invalidate () في الوقت المناسب لمسح الجلسة. يمكن عادةً استدعاء طريقة httpsession.invalidate () على صفحة خروج التطبيق.
25. لا تعلن الصفيف على النحو التالي: نهائي ثابت عام.
26. مناقشة حول كفاءة اجتياز هاشماب
غالبًا ما تكون هناك عمليات اجتياز على أزواج المفتاح والقيمة في HashMap ، وهناك طريقتان: MAP <String ، String []> paramap = جديد
HashMap <string ، string []> () ؛ ............ // مجموعة الحلقة الأولى <string> AppFieldDefids = paramap.keyset () ؛ ] القيم = paramap.get (appfielddefid) ؛ ......} // الحلقة الثانية لـ (إدخال <string ، string []> الإدخال: paramap.entryset ()) {String appfieldDefid = interph.getKey ( ) ؛ String [] القيم = intern.getValue () ؛ .......} التنفيذ الأول أقل كفاءة من التنفيذ الثاني.
التحليل كما يلي Set <String> AppFieldDefids = paramap.keyset () ؛
الرمز كما يلي:
مجموعة عامة <k> keyyset () {set <k> ks = keyset ؛ return (ks! = null؟ ks: (keyset = new keyset ()) ؛} مفاتيح الفئة الخاصة يمتد ملخص <k> {iterator public <k > iterator () {return newKeyIterator () ؛} public int size () {return size ؛} يحتوي المنطقي العام على (كائن O) (O)! = null ؛} void public clear () {hashmap.tis.clear () ؛}}في الواقع ، فإنه يعيد مفاتيح فئة خاصة ، ورثت من Abstractset وينفذ الواجهة المحددة.
دعونا نلقي نظرة على بناء الجملة لـ/في الحلقات
ل (إعلان: التعبير)
إفادة
خلال مرحلة التنفيذ ، يتم ترجمته إلى الصيغ التالية
لـ (iterator <e> #i = (التعبير) .iterator () ؛ #i.hashNext () ؛) {
الإعلان = #i.next () ؛
إفادة
}
لذلك ، يتم استدعاء hashmap.keyset (). iterator () في أول بيان لـ (String AppFieldDefid: AppFieldDefids)
هذه الطريقة تستدعي NewKeyIterator ()
iterator <k> newKeyiterator () {
إرجاع keyiterator new new () ؛
}
keyiterator من الفئة الخاصة يمتد hashiterator <k> {
العام k التالي () {
إرجاع nextentry (). getKey () ؛
}
}
لذلك في for ، يتم استدعاء iterator المستخدم في الحلقة الثانية لـ (الإدخال <string ، string []>: paramap.entryset ()) على النحو التالي.
عطوف
Entpliiterator من الفئة الخاصة يمتد hashiterator <map.entry <k ، v >> {
الخريطة العامة. entry <k ، v> next () {
إرجاع nextentry () ؛
}
}
في هذا الوقت ، تحصل الحلقة الأولى على المفتاح ، والحلقة الثانية تحصل على كفاءة دخول HashMap هي أن الحلقة الثانية تنعكس في الحلقة. استخدم طريقة GET (مفتاح الكائن) للحصول على القيمة
public v get (مفتاح الكائن) {
كائن k = masknull (مفتاح) ؛
int hash = hash (k) ؛
int i = indexfor (hash ، table.length) ؛
الدخول <k ، v> e = table ؛
بينما (صحيح) {
إذا (e == null)
العودة لاغية.
if (e.hash == hash && eq (k ، e.key))
إرجاع E.Value ؛
e = e.next ؛
}
}
في الواقع ، هو استخدام قيمة التجزئة للحصول على الإدخال المقابل مرة أخرى للمقارنة والحصول على النتيجة.
في الحلقة الثانية ، تحصل على قيمة الإدخال ثم تأخذ المفتاح والقيمة مباشرة ، وهو أكثر كفاءة من الحلقة الأولى. في الواقع ، وفقًا لمفهوم الخريطة ، يجب أن يكون من الأفضل استخدام الحلقة الثانية.
27. استخدام المصفوفة (صفيف) و ArryList
Array ([]): الأكثر كفاءة ؛
ArrayList: يمكن أن تنمو بشكل ديناميكي ؛
بناءً على الكفاءة والتحقق من النوع ، يجب استخدام الصفيف قدر الإمكان.
ArrayList هي نسخة معقدة من المصفوفة
يقوم ArrayList بتغليف مجموعة من نوع الكائنات بشكل عام طريقة الصفيف.
عندما يخزن ArrayList كائنًا ، يتم التخلص من معلومات النوع ويتم حظر جميع الكائنات ككائن.
ملاحظة: أضافت JDK5 دعمًا للأشكال ، ويمكن إجراء فحص النوع عند استخدام ArrayList.
من وجهة النظر هذه ، يرجع الفرق بين ArrayList و Array بشكل رئيسي إلى كفاءة زيادة السعة الديناميكية.
28. حاول استخدام HashMap و ArtyList .
29. الفرق بين StringBuffer و StringBuilder:
Java.lang.StringBuffer Safe-Safe Sequence Formence. مخزن مؤقت لسلسلة تشبه السلسلة ، ولكن لا يمكن تعديله.
StringBuilder. بالمقارنة مع هذه الفئة ، يجب عادةً تفضيل فئة java.lang.stringBuilder لأنها تدعم جميع العمليات نفسها ، ولكنها أسرع لأنها لا تؤدي المزامنة. لتحسين الأداء ، يجب تحديد قدرة aristngbuffer أو aristngbuilder قدر الإمكان. بالطبع ، إذا كانت السلسلة التي تديرها لا تتجاوز طولها 16 حرفًا ، فلن تحتاج إليها. في نفس الحالة ، يمكن لاستخدام aristngbuilder تحقيق تحسين الأداء حوالي 10 ٪ -15 ٪ مقارنة باستخدام StringBuffer ، ولكنه يتطلب خطر عدم الأمان متعدد الخيوط. في البرمجة المعيارية الحقيقية ، قد لا يتمكن المبرمج المسؤول عن وحدة معينة من تحديد ما إذا كانت الوحدة سيتم وضعها في بيئة متعددة الخيوط ، لذلك: ما لم تتمكن تأكد من أن الوحدة النمطية لن يتم تشغيلها في وضع MultiTerded ، وإلا استخدم StringBuffer.
مكملات أخرى:
1. كائنات واضحة لم تعد تستخدم في الوقت المناسب وتعيينها على NULL
2. استخدم الكلمات الرئيسية النهائية والثابتة وغيرها قدر الإمكان
3. استخدم الكائنات المخزنة قدر الإمكان
كيفية تحسين التعليمات البرمجية لجعل ملف مصدر Java وتجميع ملف الفئة أصغر
1 حاول استخدام الميراث.
2 افتح خيارات التحسين لمرجم Java: Javac -o سيحذف هذا الخيار رقم السطر في ملف الفئة ويعلن عن بعض الأساليب الخاصة بالقطاع الصغيرة والثابت
3 استخراج الكود المشترك
4 لا تهيئة المصفوفات الكبيرة. مخزنة في صفيف ، يمكنك أولاً وضع هذه البيانات في سلسلة ، ثم تحليل السلسلة في صفيف أثناء وقت التشغيل
5. سيستغرق كائنات نوع التاريخ مساحة كبيرة
نوع طويل ، ثم قم بتحويل نوع التاريخ عند استخدامه
6. حاول استخدام أسماء قصيرة لأسماء الفصول الدراسية وأسماء المتغيرات.
7 تحديد متغيرات النوع النهائي الثابت في الواجهة
8 إذا كان يمكن استخدام العمليات الحسابية للحركة اليمنى / اليمين ، فلا تستخدم * و / العمليات.
2. لا تهيئة المتغيرات مرتين
تقوم Java بتهيئة المتغير إلى قيمة معروفة بشكل افتراضي من خلال استدعاء مُنشئ فئة فريد. يتم ضبط جميع الكائنات على NULL ، يتم تعيين أعداد صحيحة (بايت ، قصيرة ، int ، طويلة) على 0 ، يتم تعيين تعويم ومضاعفة على 0.0 ، ويتم ضبط متغيرات منطقية على خطأ. هذا مهم بشكل خاص للفئات التي تمتد من فئات أخرى ، تمامًا مثل جميع سلسلة المُنشئين تلقائيًا عند إنشاء كائن باستخدام كلمة رئيسية جديدة.
3. اجعل الفصل النهائي كلما أمكن ذلك
لا يمكن تمديد الطبقات النهائية. هناك الكثير من الأمثلة على هذه التكنولوجيا في API Core Java ، مثل java.lang.string. وضع علامة على فئة السلسلة كنهائي يمنع المطورين من إنشاء طرق الطول التي ينفذونها بأنفسهم.
لوضعها بعمق أكبر ، إذا كان الفصل نهائيًا ، فكل طرق الفصل نهائية. قد يدخل برنامج التحويل البرمجي Java جميع الطرق (هذا يعتمد على تنفيذ المترجم). في اختباراتي ، رأيت زيادة في الأداء بنسبة 50 ٪.
9. يتم إلقاء الاستثناء حيث يجب إلقاؤه.
جرب {some.method1 () ؛ (Method2Exception e) {// handled exception 2} جرب {some.method3 () ؛ من الأسهل تحسين الرمز الذي تم تنزيله
جرب {some.method1 () ؛ catch (method3Exception e) {// handled insistrice 3}
10. تحسين الحلقة
يستبدل…
لـ (int i = 0 ؛ i <collection.size () ؛ i ++) {
...
}
مع…
لـ (int i = 0 ، n = collection.size () ؛ i <n ؛ i ++) {
...
}
5. في تطوير نظام تطبيق Java + Oracle ، حاول استخدام بيانات SQL المدمجة من النماذج الكبيرة في Java لتقليل عبء التحليل الخاص بـ Oracle Parser.
10. حاول تبني استراتيجية التحميل البطيئة ، أي ابدأ في الإنشاء عند الحاجة.
على سبيل المثال: String str = "aaa" ؛
إذا (i == 1) {
list.add (str) ؛
}
يجب استبداله:
إذا (i == 1) {
سلسلة str = "aaa" ؛
list.add (str) ؛
}
12. لا تستخدمه في حلقة:
يحاول {
} يمسك() {
}
يجب وضعه على الطبقة الخارجية
ما سبق هو كل شيء عن هذا المقال.
يرجى قضاء بعض الوقت لمشاركة المقالة مع أصدقائك أو ترك تعليق. سنشكر بإخلاص على دعمكم!