2011-08-23 19 views
7

आप अधिक कुशल मानेंगे?जावा एनम मूल्य दक्षता

public enum WeekDay { 
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY; 
} 

लूप के माध्यम से और सत्यापित करें दिन पहली स्ट्रिंग:

public void parseString(String line) { 
    String[] tokens = line.split(); 
    String day = tokens[1]; // day 'should' always be a weekday 
    if (isValidWeekDay(day)) { 
     WeekDay weekDay = WeekDay.valueOf(day); // won't throw exception 
     ... 
    } else { 
     throw new InvalidWeekDayException(day); // subclass of RuntimeException 
    } 
} 
private boolean isValidWeekDay(String day) { 
    for (WeekDay weekDay : WeekDay.values()) { 
     if(weekDay.toString().equals(day)) 
      return true; 
    } 
    return false; 
} 

या मामलों की 99.99% में के बाद से, दिन सही हो जाएगा

'काम करने के दिन' का उपयोग सिर्फ एक उदाहरण है:

public void parseString(String line) { 
    String[] tokens = line.split(); 
    String day = tokens[1]; // day 'should' always be a weekday 
    try { 
     WeekDay weekDay = WeekDay.valueOf(day); // might throw exception 
     ... 
    } catch (IllegalArgumentException e) { 
     throw new InvalidWeekDayException(day, e); 
    } 
} 

अद्यतन:

स्पष्टीकरण के लिए, इनपुट स्ट्रिंग उपयोगकर्ता के बजाए क्लाइंट एप्लिकेशन से आएगी। तो दूसरे शब्दों में, यह इस उदाहरण में एक गैर कार्यदिवस प्राप्त करने के लिए एक बग होगा।

+7

यह एक मुखर उत्तर की तरह लग सकता है, लेकिन मैं सबसे तेज़ दौड़ने पर विचार करता हूं जब मैंने इसे सबसे कुशल माना। –

+0

क्या स्ट्रिंग किसी उपयोगकर्ता से प्रवेश करता है, या यह आंतरिक रूप से आ रहा है? – DHall

+0

मैं इसके बजाय इसका उपयोग करूंगा, अगर आप वास्तव में सप्ताह के दिनों में enum कर रहे हैं: http://joda-time.sourceforge.net/field.html#dayOfWeek – NimChimpsky

उत्तर

4

मुझे इसकी पुरानी पोस्ट पता है, लेकिन मेरा मानना ​​है कि निम्नलिखित परिणाम अभी भी दिलचस्प होंगे। मैं जेडीके 1.8 का उपयोग कर enum ENUM {FIRST, SECOND, THIRD, FOURTH, LAST} में एक तत्व खोजने के लिए 10000000 परीक्षण चलाता हूं। नीचे दी गई तालिका सरल लूप और valueOf() द्वारा आवश्यक समय दिखाती है।

 
text  loop valueOf ratio 
------------------------------ 
"FIRST" 121 65  186% 
"LAST" 188 57  330% 
"foo" 155 8958  1.7% 

निष्कर्ष - मैं valueOf() का उपयोग नहीं होता है, तो मैं मान enum मिलान नहीं की उम्मीद है।

+0

क्या आपका परीक्षण तब अपवाद का उपयोग करने की दक्षता हिट पर केंद्रित था? या valueOf() विधि में कुछ कार्यान्वयन विस्तार का अंतर बी/सी था? क्या आपने इसे जेआईटी सक्षम के साथ सामान्य रूप से चल रहे JVM (यानी डीबग मोड में नहीं) में चलाया था? और तुम पुनरावृत्तियों की एक गुच्छा के माध्यम से बन रहे इससे पहले कि आप अपने टाइमर शुरू कर दिया द्वारा JIT को गर्म किया?जब मैंने ज़क्सिंग के साथ अपना परीक्षण किया, तो मैंने देखा कि जब आप डीबग मोड में परीक्षण चलाते हैं तो आप किस तरह के अंतर दिखा रहे हैं - लेकिन एक बार डीबगर रास्ते से बाहर हो जाने के बाद, प्रदर्शन काफी समान था। –

+0

हे @ केविन। ऐसे कई पैरामीटर हैं जो तालिका में ठोस आंकड़ों को प्रभावित कर सकते हैं। मैं _my environment_ (ओरेकल जेवीएम 1.6 + 64-बिट Win7 + डीबग मोड) में "अपवाद की लागत" के बारे में उत्सुक था। मैं परिणाम से इतना हैरान था कि मैंने इसे प्रकाशित करने का फैसला किया। मुझे अपने सी ++ अनुभव के आधार पर सबसे खराब मामले में 10-20% अनुपात की उम्मीद है। – aknopov

2

HashSet में मान्य तारों को स्टोर करें, और यह तय करें कि कोई स्ट्रिंग मान्य दिन है या Set.contains(...) पर आधारित नहीं है।

सेट एक static final Set हो सकता है, और आप अच्छा उपाय के लिए एक unmodifiable में लपेट कर सकते हैं:

private static final Map<String> WEEKDAY_STRINGS; 
static { 
    HashSet<String> set = new HashSet(); 
    for (WeekDay d : WeekDay.values()) { 
    set.add(d.toString()); 
    } 
    WEEKDAY_STRINGS = Collections.unmodifiableSet(set); 
} 
+1

यह समस्या आईएमएच – NimChimpsky

2

पाश कुछ भी है कि valueOf नहीं, वे ही कार्यक्षमता है करता कॉल नहीं करता है: चेकिंग चाहे आपकी स्ट्रिंग मान्य enum है। आपको लगता है कि आपको पहले विकल्प से क्या फायदा होता है?

दूसरा विकल्प सबसे अच्छा है:

try { 
    WeekDay weekDay = WeekDay.valueOf(day); // might throw exception 
     ... 
    } catch (IllegalArgumentException e) { 
     throw new InvalidWeekDayException(day); 
    } 
+0

समस्या को खत्म कर रहा है, मुझे लगता है कि यह सब कुछ अमान्य दिन कितने आम हैं। यदि 50% दिन अमान्य थे, तो कुछ अपवाद को फेंकने/पकड़ने में बहुत अक्षम होंगे। हालांकि अगर यह केवल दुर्लभ क्लाइंट एप्लिकेशन बग है, तो यह निश्चित रूप से जाने का तरीका है। – toolkit

2

या फिर आप अपने enum अंदर enum मूल्यों की एक देखने बनाते समय कक्षा पहली बार लोड (स्थिर संशोधक देखें) और जैसा कि नीचे दिखाया get() का उपयोग को मान्य कर सकते हैं:

private String dayName; 
private static final Map<String,Weekday> lookup = new HashMap<String, Weekday>(); 
static{ 
    for (Weekday day: values()){ 
     lookup.put(day.dayName, d); 
    } 
} 
public static Weekday get(String _name){ 
    return lookup.get(_name); 
} 

अगर आप अधिक विवरण

5

की जरूरत के रूप में टिप्पणी की गई है, आपको यह सुनिश्चित करने के लिए पता लगाने के लिए प्रोफ़ाइल करना होगा मुझे जानते हैं। यहां तक ​​कि अपने स्वयं के पार्सिंग दृष्टिकोण में, जब आप सूची को पार्स करते हैं तो आप enum को वापस करके इसे तेज़ी से बना सकते हैं।

private WeekDay getValidWeekDay(String day) { 
    for (WeekDay weekDay : WeekDay.values()) { 
     if(weekDay.toString().equals(day)) 
      return weekDay; 
    } 
    return null; 
} 

जब तक यह एक आवेदन के समय के महत्वपूर्ण टुकड़ा है, मैं या तो मामले में इसके बारे में चिंता नहीं होगी और केवल सबसे पठनीय दृष्टिकोण रखना। मुझे लगता है कि सप्ताहांत .valueOf() विधि का उपयोग करेगा।

यदि आपको अपवादों से निपटने की ज़रूरत नहीं है, तो enum के भीतर अपने मूल्यों का नक्शा बनाएं और प्रभावी रूप से valueOf() के बराबर करें जो लुकअप से मिलता है जो शून्य नहीं होता है।

public enum WeekDay { 
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY; 

    private static Map<String, WeekDay> valueMap; 

    public static WeekDay getValue(String possibleName) 
    { 
     if (valueMap == null) 
     { 
      valueMap = new HashMap<String, WeekDay>(); 
      for(WeedDay day: values()) 
       valueMap.put(day.toString(), day); 
     } 
     return valueMap.get(possibleName); 

    } 
} 

यह प्रभावी रूप से है क्या valueOf() विधि वैसे भी कर रहा है, सिवाय इसके कि इसे IllegalArgumentException फेंकता है जब यह नहीं मिला है। यह दृष्टिकोण बस शून्य वापस आ जाएगा, इस प्रकार स्टैकट्रैस उत्पन्न नहीं करेगा।

8

दूसरे दृष्टिकोण के बारे में प्रदर्शन चिंता क्या है? इस तरह के अपवाद को पकड़ना लगभग कुछ भी नहीं है। सामान्य नियंत्रण प्रवाह के लिए अपवादों का उपयोग करना आम तौर पर एक डिजाइन परिप्रेक्ष्य से एक बुरा विचार है, जिस दिन यह एक प्रदर्शन विचार था, लंबे समय तक चला गया।एक डीबगर में, महत्वपूर्ण नियंत्रण संचालन के रूप में अपवादों का उपयोग करके चीजों को लगभग 10 के कारक से धीमा कर दिया जाएगा। लेकिन यह जेआईटी द्वारा अनुकूलित किया जाता है और उत्पादन में कोई मापनीय प्रभाव नहीं होता है।

ये संख्याएं zxing प्रोजेक्ट के मूल्यांकन के साथ अनुभव पर आधारित हैं, जो प्रवाह नियंत्रण के सभी प्रकार के अपवादों का उपयोग करती है। जब मैंने इसे पहली बार देखा, तो मैं डर गया था। मुझे अभी भी लगता है कि यह सबसे अच्छा डिज़ाइन नहीं है, लेकिन मैंने काफी परीक्षण किया है और आत्मविश्वास के साथ कह सकता है कि इसका प्रदर्शन पर कोई वास्तविक प्रभाव नहीं पड़ा। और यह एक एल्गोरिदम है जो प्रवाह नियंत्रण के लिए सभी जगह अपवादों का उपयोग कर रहा था। आपकी स्थिति, जहां अपवाद केवल असाधारण परिस्थितियों में फेंक दिया जाएगा, एक गैर मुद्दा है।

संपादित करें: मेरे पास मेरे जवाब पर एक डाउनवोट या दो है, और मैं यह सुनिश्चित करना चाहता हूं कि मैं जो कह रहा हूं उस पर मैं स्पष्ट हूं: मुझे नहीं लगता कि अपवादों का उपयोग करना एक अच्छा विचार है सामान्य नियंत्रण प्रवाह। सिर्फ इसलिए कि प्रदर्शन अपवादों का उपयोग न करने के लिए एक अच्छा तर्क नहीं है, इसका मतलब यह नहीं है कि अन्य, पूरी तरह वैध कारण नहीं हैं (जैसे पठनीयता, टेस्टेबिलिटी, विस्तारशीलता)। ओपी के मामले में, अपवाद का उपयोग पूरी तरह से बुलाया जाता है, और निश्चित रूप से किसी भी प्रकार की प्रदर्शन समस्या का कारण नहीं बनता है।

+1

सलाह केविन के लिए धन्यवाद। – toolkit

3

यदि आपका प्रश्न वास्तव में 7 आइटमों के बीच खोज करने की दक्षता के बारे में है तो आप पहले से ही बहुत अधिक समय बर्बाद कर चुके हैं। यहां तक ​​कि सबसे तेज़ खोज एल्गोरिदम ओ (15) के अलावा एन> 15 या तो तक शून्य या नकारात्मक लाभ उत्पन्न करते हैं।

संबंधित मुद्दे