2012-10-26 12 views
16

मैं जावा सूची पुनरावृत्ति कोड पर कुछ माइक्रो बेंचमार्क चला रहा हूं। मैंने उपयोग किया है -XX: + प्रिंटकंपिलेशन, और -verbose: जीसी झंडे यह सुनिश्चित करने के लिए कि पृष्ठभूमि में कुछ भी नहीं हो रहा है जब समय चल रहा है। हालांकि, मुझे आउटपुट में कुछ दिखाई देता है जिसे मैं समझ नहीं पा रहा हूं।-XX के आउटपुट को समझना: + प्रिंटकंपिलेशन

यहाँ कोड है, मैं पर बेंचमार्क चला रहा हूँ:

import java.util.ArrayList; 
import java.util.List; 

public class PerformantIteration { 

    private static int theSum = 0; 

    public static void main(String[] args) { 
     System.out.println("Starting microbenchmark on iterating over collections with a call to size() in each iteration"); 
     List<Integer> nums = new ArrayList<Integer>(); 
     for(int i=0; i<50000; i++) { 
      nums.add(i); 
     } 

     System.out.println("Warming up ..."); 
     //warmup... make sure all JIT comliling is done before the actual benchmarking starts 
     for(int i=0; i<10; i++) { 
      iterateWithConstantSize(nums); 
      iterateWithDynamicSize(nums); 
     } 

     //actual   
     System.out.println("Starting the actual test"); 
     long constantSizeBenchmark = iterateWithConstantSize(nums); 
     long dynamicSizeBenchmark = iterateWithDynamicSize(nums); 
     System.out.println("Test completed... printing results"); 

     System.out.println("constantSizeBenchmark : " + constantSizeBenchmark); 
     System.out.println("dynamicSizeBenchmark : " + dynamicSizeBenchmark); 
     System.out.println("dynamicSizeBenchmark/constantSizeBenchmark : " + ((double)dynamicSizeBenchmark/(double)constantSizeBenchmark)); 
    } 

    private static long iterateWithDynamicSize(List<Integer> nums) { 
     int sum=0; 
     long start = System.nanoTime();   
     for(int i=0; i<nums.size(); i++) { 
      // appear to do something useful 
      sum += nums.get(i); 
     }  
     long end = System.nanoTime(); 
     setSum(sum); 
     return end-start; 
    } 

    private static long iterateWithConstantSize(List<Integer> nums) { 
     int count = nums.size(); 
     int sum=0; 
     long start = System.nanoTime();   
     for(int i=0; i<count; i++) { 
      // appear to do something useful 
      sum += nums.get(i); 
     } 
     long end = System.nanoTime(); 
     setSum(sum); 
     return end-start; 
    } 

    // invocations to this method simply exist to fool the VM into thinking that we are doing something useful in the loop 
    private static void setSum(int sum) { 
     theSum = sum;  
    } 

} 


यहाँ उत्पादन है।

152 1  java.lang.String::charAt (33 bytes) 
    160 2  java.lang.String::indexOf (151 bytes) 
    165 3Starting microbenchmark on iterating over collections with a call to size() in each iteration  java.lang.String::hashCode (60 bytes) 
    171 4  sun.nio.cs.UTF_8$Encoder::encodeArrayLoop (490 bytes) 
    183 5 
     java.lang.String::lastIndexOf (156 bytes) 
    197 6  java.io.UnixFileSystem::normalize (75 bytes) 
    200 7  java.lang.Object::<init> (1 bytes) 
    205 8  java.lang.Number::<init> (5 bytes) 
    206 9  java.lang.Integer::<init> (10 bytes) 
    211 10  java.util.ArrayList::add (29 bytes) 
    211 11  java.util.ArrayList::ensureCapacity (58 bytes) 
    217 12  java.lang.Integer::valueOf (35 bytes) 
    221 1%  performance.api.PerformantIteration::main @ 21 (173 bytes) 
Warming up ... 
    252 13  java.util.ArrayList::get (11 bytes) 
    252 14  java.util.ArrayList::rangeCheck (22 bytes) 
    253 15  java.util.ArrayList::elementData (7 bytes) 
    260 2%  performance.api.PerformantIteration::iterateWithConstantSize @ 19 (59 bytes) 
    268 3%  performance.api.PerformantIteration::iterateWithDynamicSize @ 12 (57 bytes) 
    272 16  performance.api.PerformantIteration::iterateWithConstantSize (59 bytes) 
    278 17  performance.api.PerformantIteration::iterateWithDynamicSize (57 bytes) 
Starting the actual test 
Test completed... printing results 
constantSizeBenchmark : 301688 
dynamicSizeBenchmark : 782602 
dynamicSizeBenchmark/constantSizeBenchmark : 2.5940773249184588 


मैं उत्पादन से इन चार लाइनों को नहीं समझते।

260 2%  performance.api.PerformantIteration::iterateWithConstantSize @ 19 (59 bytes) 
268 3%  performance.api.PerformantIteration::iterateWithDynamicSize @ 12 (57 bytes) 
272 16  performance.api.PerformantIteration::iterateWithConstantSize (59 bytes) 
278 17  performance.api.PerformantIteration::iterateWithDynamicSize (57 bytes) 


  • क्यों इन दोनों तरीकों दो बार संकलित किया जा रहा है?
  • मैं इस आउटपुट को कैसे पढ़ूं ... विभिन्न संख्याओं का क्या अर्थ है?
+0

धन्यवाद @Thomas JUNGBLUT सुनिश्चित नहीं हैं कि मैं -XX से चूक गए: से + PrintCompilation शीर्षक – Parag

+2

एनपी, यहां संकलन के बारे में एक अच्छा संसाधन है: https://gist.github.com/1165804#file_notes.md –

उत्तर

15

मैं की सहायता से Thomas Jungblut द्वारा पोस्ट किए गए अपने प्रश्न का उत्तर देने का प्रयास करने जा रहा हूं।

260 2%  performance.api.PerformantIteration::iterateWithConstantSize @ 19 (59 bytes) 
268 3%  performance.api.PerformantIteration::iterateWithDynamicSize @ 12 (57 bytes) 
272 16  performance.api.PerformantIteration::iterateWithConstantSize (59 bytes) 
278 17  performance.api.PerformantIteration::iterateWithDynamicSize (57 bytes) 

पहला कॉलम

प्रथम स्तंभ '260' टाइमस्टैम्प है।

दूसरा स्तंभ

दूसरे स्तंभ compilation_id और method_attributes है। जब हॉटस्पॉट संकलन ट्रिगर होता है, तो प्रत्येक संकलन इकाई को संकलन आईडी मिलती है। दूसरे कॉलम में संख्या संकलन आईडी है। जेआईटी संकलन, और ओएसआर संकलन में संकलन आईडी के लिए दो अलग-अलग अनुक्रम हैं। तो 1% और 1 अलग संकलन इकाइयां हैं। पहली दो पंक्तियों में%, इस तथ्य का संदर्भ लें कि यह एक ओएसआर संकलन है। एक ओएसआर संकलन ट्रिगर किया गया था क्योंकि कोड एक बड़े पाश पर लूपिंग था, और वीएम ने निर्धारित किया कि यह कोड गर्म है। तो एक ओएसआर संकलन ट्रिगर किया गया था, जो वीएम को ऑन स्टैक रिप्लेसमेंट करने में सक्षम बनाता है और इसे तैयार होने के बाद अनुकूलित कोड पर ले जाता है।

तीसरा स्तंभ

तीसरे स्तंभ performance.api.PerformantIteration::iterateWithConstantSize विधि का नाम है। जब OSR संकलन होता है और जब यह होता है नहीं

चौथा स्तंभ

चौथे स्तंभ फिर से अलग है। आइए पहले आम भागों को देखें। चौथे स्तंभ (5 9 बाइट्स) का अंत, बाइटकोड में संकलन इकाई के आकार को संदर्भित करता है (संकलित कोड का आकार नहीं)। ओएसआर संकलन में @ 1 9 भाग osr_bci को संदर्भित करता है।मैं लिंक ऊपर उल्लेख से उद्धृत करने के लिए जा रहा हूँ - एक जावा विधि में

एक "जगह" अपने बाईटकोड सूचकांक (बीसीआई), और जगह है कि एक OSR संकलन शुरू हो रहा "osr_bci" कहा जाता है द्वारा परिभाषित किया गया है । एक ओएसआर-संकलित एनएम विधि केवल अपने osr_bci से दर्ज किया जा सकता है; वहां उसी विधि के एकाधिक ओएसआर-संकलित संस्करण हो सकते हैं, उसी समय पर, जब तक उनका osr_bci भिन्न होता है।

अंत में, विधि दो बार संकलित क्यों हुई?

पहला एक ओएसआर संकलन है, जो संभवतया हुआ था जबकि लूप गर्मजोशी कोड (उदाहरण में) के कारण चल रहा था, और दूसरा संकलन एक जेआईटी संकलन है, संभवतः संकलित कोड को और अनुकूलित करने के लिए?

+0

यदि आप गर्म होने के दौरान ओएसआर कोड प्राप्त कर रहे हैं "आप इसे गलत कर रहे हैं"। JVM के तर्कों को भी सूचीबद्ध करें, यह केवल सी 1 (क्लाइंट/गूंगा कंपाइलर) और सी 2 (स्मार्ट, धीमी कंपाइलर) हो सकता है। पुनर्मूल्यांकन deoptimization के परिणाम भी हो सकता है। सबसे आसान (?) तरीका जेनरेट कोड सूचीबद्ध कर रहा है, यदि आप सी 1 स्टब्स देखते हैं, तो आप जानते हैं कि यह सी 1 कोड है। – bestsss

+0

@bestsss वह क्यों है? मुझे लगता है कि ओएसआर संकलन हो रहा है क्योंकि उदाहरण के वार्मअप कोड में एक बड़ा पाश कहा जाता है। – Parag

+0

मेरा मुद्दा यह है कि यदि आप कुछ भी गर्म करने का प्रयास करते हैं, तो आपको ओएसआर से बचना चाहिए, इसे छोटे तरीकों से विभाजित करना चाहिए। – bestsss

-1

मैं पहली बार OSR हुआ लगता है, तो यह प्रार्थना किए काउंटर Tigger पद्धति को बदलने compilar (पुनश्च: पूल माफ करना, मेरी अंग्रेजी है)