سؤال

أنا فقط كتبت فقرة كاملة حول كيفية توصلت إلى هذه النقطة، لكنها اكتشفت أنه من الأسهل نشر التعليمات البرمجية واتركها في ذلك :)

بقدر ما أستطيع أن أقول، يجب أن يكون أداء Test3 () هو نفسه Test1 () - الفرق الوحيد هو المكان الذي يتم فيه اكتشاف الاستثناء (داخل طريقة الاتصال ل Test1 ()، داخل الطريقة المسمى Test3 ())

لماذا يستغرق الاختبار 3 () بانتظام بعض الوقت في مكان ما بين Test1 () و Test2 () لإكماله؟

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public class Test {

    public static void main(String[] args) {
        warmup(); 
        test1(2500000); // Exception caught inside the loop
        test2(2500000); // Exception caught outside the loop
        test3(2500000); // Exception caught "inside" the loop, but in the URLEncoder.encode() method
    }

    private static void warmup() {
        // Let URLEncoder do whatever startup it needs before we hit it
        String encoding = System.getProperty("file.encoding");
        try {
            URLEncoder.encode("ignore", encoding);
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private static void test1(int count) {
        String encoding = System.getProperty("file.encoding");
        long start = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            try {
                URLEncoder.encode("test 1 " + i, encoding);
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("Performed " + count + " encodings trying to catch each in " + (end - start) + "ms");
    }

    private static void test2(int count) {
        String encoding = System.getProperty("file.encoding");
        long start = System.currentTimeMillis();
        try {
            for (int i = 0; i < count; i++) {
                URLEncoder.encode("test 2" + i, encoding);
            }
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("Performed " + count + " encodings trying to catch all in " + (end - start) + "ms");
    }

    private static void test3(int count) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            URLEncoder.encode("test 3 " + i);
        }
        long end = System.currentTimeMillis();
        System.out.println("Performed " + count + " encodings with a deprecated method in " + (end - start) + "ms");
    }

}

تشغيله يعطيني (JDK 1.6.0_13 على نظام التشغيل Windows XP) الإخراج:

Performed 2500000 encodings trying to catch each in 4906ms
Performed 2500000 encodings trying to catch all in 2454ms
Performed 2500000 encodings with a deprecated method in 2953ms

لذلك، تكون الردود قريبة جدا (نحن نتحدث شيئا ما هو غير ذي صلة به)، btu أنا فضولي!

في وقت لاحق...

اقترح الناس أن هناك تحسين JVM في الطريق - أوافق. لذلك، لقد كسرت كل اختبار لأسفل في طريقة الطبقة / الرئيسية الخاصة بها وكل منها بشكل فردي. النتائج من هذا:

1 - Performed 2500000 encodings trying to catch each in 5016ms
1 - Performed 5000000 encodings trying to catch each in 7547ms
1 - Performed 5000000 encodings trying to catch each in 7515ms
1 - Performed 5000000 encodings trying to catch each in 7531ms

2 - Performed 2500000 encodings trying to catch all in 4719ms
2 - Performed 5000000 encodings trying to catch all in 7250ms
2 - Performed 5000000 encodings trying to catch all in 7203ms
2 - Performed 5000000 encodings trying to catch all in 7250ms

3 - Performed 2500000 encodings with a deprecated method in 5297ms
3 - Performed 5000000 encodings with a deprecated method in 8015ms
3 - Performed 5000000 encodings with a deprecated method in 8063ms
3 - Performed 5000000 encodings with a deprecated method in 8219ms

ملاحظات مثيرة للاهتمام:

  • يتم تقليل الفجوة بين الحصول على كل مكالمة مقابل الحصول على كل شيء خارج الحلقة في jvm الخاصة بها (أفترض أن الأمثل لا يذهب إلى الخنزير بأكمله في حالة الاختبارات الواحدة بسبب التكرارات الأخرى التي تم إجراؤها)
  • الفجوة بين المحاولة / الصيد على جانبي مقابل TRY / CATCK داخل Urlencoder.Encode () أصبح الآن أصغر بكثير (نصف ثاني أكثر من 5000000 تكرار) ولكن لا يزال هناك ...
هل كانت مفيدة؟

المحلول

تشغيله بالترتيب الذي نشرته:

أداء 2500000 ترميزات تحاول التقاط كل منها في 34208ms
أداء 2500000 ترميزات تحاول التقاط الكل في 31708ms
أجريت 2500000 ترميزات مع طريقة مهملة في 30738ms

عكس النظام:

أجريت 2500000 ترميزات مع طريقة مهملة في 32598ms
أداء 2500000 ترميزات تحاول التقاط الكل في 31239ms
أداء 2500000 ترميزات تحاول التقاط كل منها في 31208ms

لذلك لا أعتقد في الواقع أنك ترى ما تعتقد أنك ترى (بالتأكيد، Test1 ليس أبطأ 66٪ من Test3، وهو ما تشير إليه معاييرك)

نصائح أخرى

نعم لديك تفسيرك، أعتقد:

3 أبطأ قليلا من 1 بسبب استدعاء الطريقة الإضافية المعنية.

2 أسرع من إما لأنه لا ينشئ "و" تمزيق "ByTecode ذات الصلة بالاستثناءات في كل حلقة. يمكنك فتح الكراك رمز البايت لرؤية الفرق مع JAVAP - انظر http://www.theserverside.com/tt/articles/article.tsss؟l=guidejavabytecode.

سواء كنت تستخدم 2 أو 1 يعتمد على السلوك الذي تريده، لأنها لا تعادل. سأختار 1 أكثر من 3 لأنك لا تستخدم طريقة محددة، وهي أكثر أهمية من الزيادات في السرعة الصغيرة - ولكن كما يحدث 1 أسرع على أي حال.

يرجى تصحيح لي، ولكن ينفذ test2 for-loop خطوة واحدة فقط، بسبب استثناء رمي واختبار 1 اشتعلت الاستثناء داخل الحلقة ويتم تنفيذها 2500000 مرة.

عندما تصطاد الاستثناء خارج الحلقة، لن تبدأ الحلقة مرة أخرى. اطبع "INT I" للتأكد من عدد الخطوات التي صنعتها الحلقة.

الثالث هو الأبطأ، لأن الطريقة تفوض الدعوة إلى الطريقة المهملة.

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