سؤال

كيف تكتب (وتدير) معيارًا دقيقًا صحيحًا في Java؟

أنا أبحث عن بعض نماذج التعليمات البرمجية والتعليقات التي توضح أشياء مختلفة يجب التفكير فيها.

مثال:هل يجب على المعيار قياس الوقت/التكرار أو التكرارات/الوقت، ولماذا؟

متعلق ب: هل قياس ساعة الإيقاف مقبول؟

هل كانت مفيدة؟

المحلول

نصائح حول كتابة المعايير الدقيقة من منشئي Java HotSpot:

القاعدة 0: اقرأ ورقة بحثية حسنة السمعة حول JVMs والقياس المرجعي الجزئي.فكرة جيدة بريان جويتز، 2005.لا تتوقع الكثير من المعايير الجزئية؛إنهم يقيسون فقط نطاقًا محدودًا من خصائص أداء JVM.

المادة 1: قم دائمًا بتضمين مرحلة إحماء تعمل على تشغيل نواة الاختبار الخاصة بك طوال الطريق، بما يكفي لتشغيل جميع عمليات التهيئة والتجميعات قبل مرحلة (مراحل) التوقيت.(التكرارات الأقل مقبولة في مرحلة الإحماء.والقاعدة الأساسية هي عدة عشرات الآلاف من تكرارات الحلقة الداخلية.)

القاعدة 2: تشغيل دائما مع -XX:+PrintCompilation, -verbose:gc, وما إلى ذلك، حتى تتمكن من التحقق من أن المترجم والأجزاء الأخرى من JVM لا يقومون بعمل غير متوقع أثناء مرحلة التوقيت الخاصة بك.

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

القاعدة 3: كن على علم بالفرق بين -client و -server, و OSR والمجموعات العادية.ال -XX:+PrintCompilation تقارير العلم مجموعات OSR مع علامة للإشارة إلى نقطة الدخول غير الأولية، على سبيل المثال: Trouble$1::run @ 2 (41 bytes).تفضل الخادم على العميل، ومنتظمًا على OSR، إذا كنت تسعى للحصول على أفضل أداء.

القاعدة 4: كن على دراية بتأثيرات التهيئة.لا تطبع للمرة الأولى خلال مرحلة التوقيت، حيث أن الطباعة تقوم بتحميل الفئات وتهيئتها.لا تقم بتحميل فئات جديدة خارج مرحلة الإعداد (أو مرحلة التقرير النهائي)، إلا إذا كنت تختبر تحميل الفصل على وجه التحديد (وفي هذه الحالة، قم بتحميل فئات الاختبار فقط).القاعدة 2 هي خط دفاعك الأول ضد مثل هذه التأثيرات.

القاعدة 5: كن على دراية بتأثيرات إزالة التحسين وإعادة الترجمة.لا تأخذ أي مسار للتعليمات البرمجية لأول مرة في مرحلة التوقيت، لأن المترجم قد يتخلص من التعليمات البرمجية ويعيد ترجمتها، بناءً على افتراض متفائل سابق بأن المسار لن يتم استخدامه على الإطلاق.القاعدة 2 هي خط دفاعك الأول ضد مثل هذه التأثيرات.

القاعدة 6: استخدم الأدوات المناسبة لقراءة أفكار المترجم، وتوقع أن تتفاجأ بالكود الذي ينتجه.افحص الكود بنفسك قبل تكوين نظريات حول ما الذي يجعل شيئًا ما أسرع أو أبطأ.

القاعدة 7: تقليل الضوضاء في قياساتك.قم بتشغيل المعيار الخاص بك على جهاز هادئ، وقم بتشغيله عدة مرات، مع التخلص من القيم المتطرفة.يستخدم -Xbatch لإجراء تسلسل للمترجم مع التطبيق، والنظر في الإعداد -XX:CICompilerCount=1 لمنع المترجم من العمل بالتوازي مع نفسه.ابذل قصارى جهدك لتقليل الحمل الزائد على GC، اضبط Xmx(كبيرة بما فيه الكفاية) يساوي Xms والاستخدام UseEpsilonGC إذا كان متاحا.

القاعدة 8: استخدم مكتبة لقياس الأداء الخاص بك لأنه من المحتمل أن يكون أكثر كفاءة وقد تم تصحيح أخطائه بالفعل لهذا الغرض الوحيد.مثل JMH, الفرجار أو معايير بيل وبولس الممتازة لجامعة كاليفورنيا في سان دييغو لجافا.

نصائح أخرى

أعلم أنه تم وضع علامة على هذا السؤال كإجابة ولكني أردت أن أذكر مكتبتين تساعداننا في كتابة المعايير الدقيقة

الفرجار من جوجل

الشروع في الدروس

  1. http://codingjunkie.net/micro-benchmarking-with-caliper/
  2. http://vertexlabs.co.uk/blog/caliper

JMH من OpenJDK

الشروع في الدروس

  1. تجنب قياس المخاطر في JVM
  2. http://nitschinger.at/Using-JMH-for-Java-Microbenchmarking
  3. http://java-performance.info/jmh/

الأشياء المهمة لمعايير Java هي:

  • قم بتسخين JIT أولاً عن طريق تشغيل الكود عدة مرات قبل التوقيت هو - هي
  • تأكد من تشغيله لفترة كافية لتتمكن من قياس النتائج في ثوانٍ أو (أفضل) عشرات الثواني
  • بينما لا يمكنك الاتصال System.gc() بين التكرارات، من الجيد تشغيله بين الاختبارات، بحيث يحصل كل اختبار على مساحة ذاكرة "نظيفة" للعمل بها.(نعم، gc() هو أكثر من تلميح من الضمان، لكنه جدا محتمل أنها ستجمع القمامة حقًا في تجربتي.)
  • أحب عرض التكرارات والوقت، ودرجة الوقت/التكرار التي يمكن قياسها بحيث تحصل الخوارزمية "الأفضل" على درجة 1.0 ويتم تسجيل الخوارزميات الأخرى بطريقة نسبية.هذا يعني أنه يمكنك الركض الجميع الخوارزميات لفترة طويلة، مع تغيير عدد التكرارات والوقت، ولكنها لا تزال تحصل على نتائج قابلة للمقارنة.

أنا الآن بصدد التدوين حول تصميم إطار عمل مرجعي في .NET.لقد حصلت على زوج ل المشاركات السابقة والتي قد تكون قادرة على إعطائك بعض الأفكار - لن يكون كل شيء مناسبًا بالطبع، ولكن قد يكون بعضها مناسبًا.

jmh هي إضافة حديثة إلى OpenJDK وقد تمت كتابتها بواسطة بعض مهندسي الأداء من Oracle.بالتأكيد تستحق نظرة.

Jmh عبارة عن أداة Java لبناء وتشغيل وتحليل معايير النانو/الصغرى/الماكرو المكتوبة بلغة Java ولغات أخرى تستهدف JVM.

معلومات مثيرة للاهتمام للغاية مدفونة فيها تعليقات عينة الاختبارات.

أنظر أيضا:

هل يجب على المعيار قياس الوقت/التكرار أو التكرارات/الوقت، ولماذا؟

ذلك يعتمد على ماذا كنت تحاول اختبار.

إذا كنت مهتما في وقت الإستجابة, ، استخدم الوقت/التكرار وإذا كنت مهتمًا بذلك الإنتاجية, ، استخدم التكرارات/الوقت.

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

إذا كنت تحاول المقارنة بين الخوارزميات، وقيام اثنين على الأقل المقاييس لكل منهما، بالتناوب النظام. أي بمعنى:.

for(i=1..n)
  alg1();
for(i=1..n)
  alg2();
for(i=1..n)
  alg2();
for(i=1..n)
  alg1();

ولقد وجدت بعض الاختلافات ملحوظة (5-10٪ في بعض الأحيان) في وقت التشغيل من نفس الخوارزمية في ممرات مختلفة ..

وأيضا، تأكد من أن <م> ن هو كبير جدا، حتى أن وقت كل حلقة هو على أقل تقدير 10 ثانية أو نحو ذلك. لمزيد من التكرار، فإن الأرقام أكثر أهمية في الوقت القياسي الخاص بك وأكثر موثوقية أن البيانات.

وهناك العديد من المخاطر المحتملة لكتابة المعايير الدقيقة في جاوة.

أولا: عليك أن تحسب مع جميع أنواع الأحداث التي تستغرق وقتا أكثر أو أقل عشوائية: جمع القمامة، والآثار التخزين المؤقت (من نظام التشغيل لملفات وحدة المعالجة المركزية للذاكرة)، IO الخ

.

ثانيا: لا يمكن أن تثق في دقة مرات قياس لفترات قصيرة جدا

ثالثا: JVM يحسن التعليمات البرمجية أثناء تنفيذ. لذلك يعمل مختلفة في نفس JVM مثيل وسوف تصبح أسرع وأسرع.

وتوصياتي: جعل المؤشر الخاص بك تشغيل بعض الثواني، وهذا هو أكثر موثوقية من وقت التشغيل على ميلي ثانية. الاحماء JVM (وسائل تشغيل المؤشر مرة واحدة على الأقل من دون قياس، أن JVM يمكن تشغيل أمثل). وتشغيل الخاص بك القياسية عدة مرات (ربما 5 مرات) ويتخذ قيمة المتوسط. تشغيل كل مؤشر الصغيرة في JVM مثيل الجديد (دعوة لكل جافا جديد القياسي) خلاف ذلك آثار تعظيم الاستفادة من JVM يمكن أن تؤثر اختبارات تشغيل في وقت لاحق. لا تنفيذ الأشياء، التي لا يتم تنفيذها في المرحلة الودية (لأن هذا قد يؤدي الى الدرجة الحمل وإعادة تجميع).

وتجدر الإشارة أيضا إلى أنه قد يكون من المهم أيضا تحليل نتائج المؤشر الصغير عند مقارنة تطبيقات مختلفة. ولذلك ينبغي بذل اختبار أهمية .

وذلك لأن A التنفيذ قد يكون أسرع خلال معظم أشواط من المؤشر من B التنفيذ. ولكن قد يكون A أيضا انتشار أعلى، وبالتالي فإن الاستفادة قياس الأداء من A لا يكون لها أي أهمية بالمقارنة مع B.

ولذا فمن المهم أيضا كتابة وتشغيل معيارا الصغيرة بشكل صحيح، ولكن أيضا لتحليل بشكل صحيح.

http://opt.sourceforge.net/ جافا مايكرو المعيار - مهام الرقابة المطلوبة لتحديد المقارن خصائص أداء نظام الكمبيوتر على منصات مختلفة. يمكن استخدامها لتوجيه القرارات الأمثل ومقارنة تطبيقات جافا مختلفة.

لإضافة لنصيحة ممتازة أخرى، ويهمني أيضا أن تضع في اعتبارها ما يلي:

لبعض وحدات المعالجة المركزية (مثل إنتل كور i5 و مجموعة مع TurboBoost)، ودرجة الحرارة (وعدد من النوى المستخدمة حاليا، وكذلك الحية واستخدامها في المئة) يؤثر على سرعة الساعة. وبما أن سجلت وحدات المعالجة المركزية بشكل ديناميكي، وهذا يمكن أن تؤثر على النتائج. على سبيل المثال، إذا كان لديك طلب واحد الخيوط، وأقصى سرعة ساعة (مع TurboBoost) أعلى من أجل تطبيق استخدام جميع النوى. وبالتالي يمكن لهذا التدخل مع مقارنات أداء واحد ومتعددة الخيوط على بعض الأنظمة. نضع في اعتبارنا أن درجة الحرارة وvolatages تؤثر أيضا كيف تردد توربو متى يتم الحفاظ عليها.

ولعل الجانب الأكثر أهمية في الأساس أن لديك السيطرة المباشرة على: تأكد من أنك قياس الشيء الصحيح! على سبيل المثال، إذا كنت تستخدم System.nanoTime() لقياس قليلا معين من التعليمات البرمجية، وضع المكالمات على احالة في الأماكن التي تجعل معنى لتجنب قياس الأشياء التي كنت لا ترغب في على سبيل المثال، لا تفعل:.

long startTime = System.nanoTime();
//code here...
System.out.println("Code took "+(System.nanoTime()-startTime)+"nano seconds");

والمشكلة هي أنك لا على الفور الحصول على نهاية الوقت عند انتهاء التعليمات البرمجية. بدلا من ذلك، حاول القيام بما يلي:

final long endTime, startTime = System.nanoTime();
//code here...
endTime = System.nanoTime();
System.out.println("Code took "+(endTime-startTime)+"nano seconds");
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top