لماذا ولدت جافا البرمجية لإجراء عملية تشغيل ببطء أكثر من مجرد "حلقة مترجم"؟

StackOverflow https://stackoverflow.com/questions/875695

سؤال

ولدي بعض شفرة جافا الذي ينفذ عمليات أحادي المعامل على BitSet. لدي قائمة من العمليات ويمكن "تفسير" لهم بواسطة حلقات عليها، ولكن من المهم بالنسبة لي أن أستطيع تنفيذ هذه العمليات في أسرع وقت ممكن، حتى لقد سعيت لإنشاء رمز لتطبيقها بشكل حيوي. I توليد مصدر جافا لتنفيذ العمليات وإعداد الطبقة تنفيذ هذه العمليات باستخدام Javassist.

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

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

ClassPool pool = ClassPool.getDefault();
CtClass tClass = pool.makeClass("foo");

// foo implements MyInterface, with one method
tClass.addInterface(pool.get(MyInterface.class.getName()));

// Get the source for the method and add it
CtMethod tMethod = CtNewMethod.make(getSource(), tClass);
tClass.addMethod(tMethod);

// finally, compile and load the class
return (MyInterface)tClass.toClass().newInstance();

هل لديها فكرة عن ما يحدث هنا؟ فما استقاموا لكم فاستقيموا نقدر حقا أي مساعدة يمكنك إعطاء.

وأنا باستخدام ملقم JVM الشمس 1.6 على نظام التشغيل Windows XP 32-بت.

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

المحلول

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

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

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

نصائح أخرى

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

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

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

وهناك إعدادات JVM التي تتحكم في كيفية كود بسرعة يجب أن يكون ترجمة -XX: CompileThreshold = 10000

<اقتباس فقرة>   

وعدد من الدعاء طريقة / الفروع قبل تجميع [-client: 1500]

وأنا لا أعرف إذا كان هذا سيساعد، لأنه في المثال الخاص بك، وحجم يبدو أن تلعب دورا حيويا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top