12

कंपाइलर के लिए अधिक कुशल कौन सा और स्ट्रिंग खाली है या नहीं, यह जांचने के लिए सबसे अच्छा अभ्यास है?स्ट्रिंग सामग्री के लिए जाँच कर रहे हैं? स्ट्रिंग लम्बाई बनाम खाली स्ट्रिंग

  1. जाँच हो रही है स्ट्रिंग == 0
  2. जांच की जा रही है कि क्या की लंबाई स्ट्रिंग (== "" strVar) रिक्त है

इसके अलावा, इस सवाल का जवाब भाषा पर निर्भर करता है कि क्या?

उत्तर

15

हां, यह भाषा पर निर्भर करता है, क्योंकि स्ट्रिंग स्टोरेज भाषाओं के बीच अलग है।

  • पास्कल-प्रकार तार: Length = 0
  • सी-शैली तार: [0] == 0
  • .NET: .IsNullOrEmpty

आदि

+2

मुझे लगता है कि ओपी खाली स्ट्रिंग सत्यापन के बारे में पूछ रहा था, न कि शून्यता, इसलिए जब आप पहले से ही जानते हैं कि स्ट्रिंग शून्य नहीं है, तो IsNullOrEmpty का उपयोग करना एक और अनावश्यक जांच है। तो ओपी का सवाल यह है कि अधिक प्रदर्शन, myString.Length> 0 या myString! = "" लेता है। Http://stackoverflow.com/questions/10230/checking-for-string-contents-string-length-vs-empty-string/2306659#2306659 – Shimmy

2

नेट में:

string.IsNullOrEmpty(nystr); 

तार, अशक्त हो सकता है तो .Length कभी कभी

0

वास्तव में एक NullReferenceException फेंकता है, यह निर्धारित करने के लिए सबसे अच्छा तरीका IMO IsNullOrEmpty है() स्ट्रिंग क्लास की विधि।

http://msdn.microsoft.com/en-us/library/system.string.isnullorempty.

अद्यतन: मैं नेट ग्रहण किया, अन्य भाषाओं में, यह भिन्न हो सकता है।

13

"" की तुलना में सी-स्टाइल (शून्य-समाप्ति) तारों का उपयोग करने वाली भाषाओं में तेज़ होगा। यह ओ (1) ऑपरेशन है, जबकि सी-स्टाइल स्ट्रिंग की लंबाई लेते समय ओ (एन) है।

लंबाई में जांच करने वाली स्ट्रिंग ऑब्जेक्ट (सी #, जावा, ...) के हिस्से के रूप में लंबाई को स्टोर करने वाली भाषाओं में ओ (1) भी है। इस मामले में, लंबाई की जांच सीधे तेज होती है, क्योंकि यह नई खाली स्ट्रिंग बनाने के ऊपरी हिस्से से बचाती है।

+3

सी # में, यदि आप स्ट्रिंग की तुलना करते हैं तो पढ़ें। लक्षण तो आप पहले से निर्मित स्ट्रिंग के खिलाफ तुलना कर रहे हैं। फिर यह ओ (1) भी है। –

1

जावा 1.6 में, स्ट्रिंग वर्ग एक नई पद्धति isEmpty

वहाँ भी जकार्ता कॉमन्स पुस्तकालय, जो isBlank विधि है है। खाली को एक स्ट्रिंग के रूप में परिभाषित किया जाता है जिसमें केवल सफेद जगह होती है।

0

इस मामले में, सीधे लंबाई की जांच तेज है, क्योंकि यह नई खाली स्ट्रिंग बनाने के ऊपरी हिस्से से बचाता है।

@DerekPark: यह हमेशा सत्य नहीं है। "" एक स्ट्रिंग अक्षर है, इसलिए जावा में, यह लगभग निश्चित रूप से पहले से ही इंटर्न किया जाएगा।

0

सी तार के लिए,

if (s[0] == 0) 

तुलना में तेजी से हो जाएगा या तो

if (strlen(s) == 0) 

या

if (strcmp(s, "") == 0) 

क्योंकि आप एक समारोह कॉल की भूमि के ऊपर से दूर रहेंगे।

2

भाषाओं का उपयोग करने वाले सी-शैली (शून्य-समाप्त) तार में, ""

वास्तव में तेजी से हो जाएगा की तुलना में, यह बेहतर हो सकता है की जांच करने के लिए यदि स्ट्रिंग में पहले चार 'है \ 0 ':

char *mystring; 
/* do something with the string */ 
if ((mystring != NULL) && (mystring[0] == '\0')) { 
    /* the string is empty */ 
} 

पर्ल में एक तीसरा विकल्प है, कि स्ट्रिंग अनिर्धारित है। यह सी में एक नल पॉइंटर से थोड़ा अलग है, अगर केवल इसलिए कि आपको एक अपरिभाषित स्ट्रिंग तक पहुंचने के लिए सेगमेंटेशन गलती नहीं मिलती है।

0

@Nathan

वास्तव में, यह बेहतर हो सकता है की जांच करने के लिए यदि स्ट्रिंग में पहले चार '\ 0' है:

मैं लगभग उल्लेख किया है कि, लेकिन यह पता छोड़ने समाप्त हो गया , खाली स्ट्रिंग के साथ strcmp() पर कॉल करने और स्ट्रिंग में पहले वर्ण की जांच करने के बाद ओ (1) दोनों हैं। आप मूल रूप से केवल एक अतिरिक्त फ़ंक्शन कॉल के लिए भुगतान करते हैं, जो कि बहुत सस्ता है। यदि आप वास्तव में को पूर्णतया सर्वोत्तम गति की आवश्यकता है, हालांकि, निश्चित रूप से प्रत्यक्ष प्रथम-चार-से-0 तुलना के साथ निश्चित रूप से जाएं।

ईमानदारी से, मैं हमेशा strlen() == 0 का उपयोग करें, क्योंकि मैं कभी नहीं एक कार्यक्रम है जहाँ यह वास्तव में एक औसत दर्जे का प्रदर्शन मुद्दा था लिखा है, और मुझे लगता है कि जांच को व्यक्त करने के लिए सबसे पठनीय तरीका है। मैं के विपरीत "String.Empty का उपयोग" क्योंकि "" एक वस्तु का निर्माण करेगा

if (inputString == null || inputString == String.Empty) 
{ 
    // String is null or empty, do something clever here. Or just expload. 
} 

:

1

String.IsNullOrEmpty() केवल .net 1/1.1 के लिए, .net 2.0 और इसके बाद के संस्करण पर काम करता है, मैं का उपयोग करते हैं , जबकि स्ट्रिंग। लक्षण नहीं है - मुझे यह कुछ छोटा और छोटा लगता है, लेकिन आईडी अभी भी ऑब्जेक्ट्स नहीं बनाते जब मुझे उनकी आवश्यकता नहीं होती! (Source)

+0

मैं वास्तव में आश्चर्यचकित हूं अगर वास्तव में सी # कंपाइलर के अंदर एक तात्कालिकता में परिणाम होता है। – jsight

+1

बेहतर प्रदर्शन –

+0

आईडी के लिए 'inputString == String.Empty' के बजाय 'inputString.Length == 0' का उपयोग करें, आईडी तर्क देता है कि inputString == String.Empty को पढ़ने के लिए आसान है। तरंगदैर्ध्य == 0 ... –

0

फिर, भाषा को जानने के बिना, यह बताना असंभव है।

हालांकि, मैं अनुशंसा करता हूं कि आप उस तकनीक का चयन करें जो रखरखाव प्रोग्रामर को सबसे ज्यादा समझ में आता है और आपके काम को बनाए रखना होगा।

मैं एक समारोह स्पष्ट करता है कि आप क्या चाहते हैं, इस तरह के रूप

#define IS_EMPTY(s) ((s)[0]==0) 

या तुलनीय लेखन सलाह देते हैं। अब इसमें कोई संदेह नहीं है कि आप जांच रहे हैं।

1

अपना प्रश्न मानना ​​है।नेट:

यदि आप अपनी स्ट्रिंग को शून्यता के साथ सत्यापित करना चाहते हैं और साथ ही IsNullOrEmpty का उपयोग करना चाहते हैं, तो यदि आप पहले से जानते हैं कि आपकी स्ट्रिंग शून्य नहीं है, उदाहरण के लिए टेक्स्टबॉक्स। टेक्स्ट इत्यादि की जांच करते समय, IsNullOrEmpty का उपयोग न करें, और उसके बाद आता है आपका प्रश्न।
तो मेरी राय के लिए स्ट्रिंग। लम्बाई स्ट्रिंग तुलना की तुलना में कम perfomance है।

मैं घटना यह परीक्षण किया (मैं भी साथ सी #, एक ही परिणाम का परीक्षण):

Module Module1 
    Sub Main() 
    Dim myString = "" 


    Dim a, b, c, d As Long 

    Console.WriteLine("Way 1...") 

    a = Now.Ticks 
    For index = 0 To 10000000 
     Dim isEmpty = myString = "" 
    Next 
    b = Now.Ticks 

    Console.WriteLine("Way 2...") 

    c = Now.Ticks 
    For index = 0 To 10000000 
     Dim isEmpty = myString.Length = 0 
    Next 
    d = Now.Ticks 

    Dim way1 = b - a, way2 = d - c 

    Console.WriteLine("way 1 took {0} ticks", way1) 
    Console.WriteLine("way 2 took {0} ticks", way2) 
    Console.WriteLine("way 1 took {0} ticks more than way 2", way1 - way2) 
    Console.Read() 
    End Sub 
End Module 

परिणाम:

Way 1... 
Way 2... 
way 1 took 624001 ticks 
way 2 took 468001 ticks 
way 1 took 156000 ticks more than way 2 

तुलना जिसका मतलब है स्ट्रिंग की लंबाई की जांच की तुलना में जिस तरह से अधिक लेता है।

+0

हालांकि, .NET में आप स्ट्रिंग के खिलाफ तुलना करके स्पष्ट स्ट्रिंग तुलना से बच सकते हैं। रिक्त स्ट्रिंग ("") के बजाय लक्षण। इससे इसे ओ (1) ऑपरेशन करना चाहिए। –

+0

मुझे लगता है कि स्ट्रिंग। लक्षण सिर्फ एक ही शाब्दिक है "", मुझे वास्तव में अंतर नहीं मिलता है। – Shimmy

+0

स्ट्रिंग। लक्षण स्ट्रिंग क्लास का एक उदाहरण है जिसका मान "" है। हालांकि बराबर के लिए स्ट्रिंग अधिभार और (==) चरित्र तुलना के लिए एक चरित्र करने से पहले एक संदर्भ तुलना करेगा। यदि संदर्भ तुलना की तुलना में संदर्भ बराबर हैं। तो स्ट्रिंग वाले मान की तुलना करना। स्ट्रिंग के लिए लक्षण। यह तुलना करने से तुलना में काफी तेज़ होगा "" जो एक नई स्ट्रिंग ऑब्जेक्ट उत्पन्न करेगा और इसके प्रारंभिक मान को "" सेट करेगा। वे वही नहीं हैं। –

0

इस धागे को पढ़ने के बाद, मैंने थोड़ा प्रयोग किया, जिसने दो अलग, और दिलचस्प, निष्कर्ष निकाले।

निम्नलिखित पर विचार करें।

strInstallString "1" string 

उपर्युक्त दृश्य स्टूडियो डीबगर की स्थानीय विंडो से कॉपी किया गया है। निम्नलिखित तीनों उदाहरणों में समान मान का उपयोग किया जाता है।

अगर (strInstallString == "") === अगर (strInstallString == string.Empty)

के बाद इन दो मौलिक समान के लिए कोड विजुअल स्टूडियो 2013 डिबगर के disassembly विंडो में प्रदर्शित है मामलों।

if (strInstallString == "") 
003126FB mov   edx,dword ptr ds:[31B2184h] 
00312701 mov   ecx,dword ptr [ebp-50h] 
00312704 call  59DEC0B0   ; On return, EAX = 0x00000000. 
00312709 mov   dword ptr [ebp-9Ch],eax 
0031270F cmp   dword ptr [ebp-9Ch],0 
00312716 sete  al 
00312719 movzx  eax,al 
0031271C mov   dword ptr [ebp-64h],eax 
0031271F cmp   dword ptr [ebp-64h],0 
00312723 jne   00312750 

if (strInstallString == string.Empty) 
00452443 mov   edx,dword ptr ds:[3282184h] 
00452449 mov   ecx,dword ptr [ebp-50h] 
0045244C call  59DEC0B0  ; On return, EAX = 0x00000000. 
00452451 mov   dword ptr [ebp-9Ch],eax 
00452457 cmp   dword ptr [ebp-9Ch],0 
0045245E sete  al 
00452461 movzx  eax,al 
00452464 mov   dword ptr [ebp-64h],eax 
00452467 cmp   dword ptr [ebp-64h],0 
0045246B jne   00452498 

अगर (strInstallString == string.Empty) नहीं काफी अलग

if (strInstallString.Length == 0) 
003E284B mov   ecx,dword ptr [ebp-50h] 
003E284E cmp   dword ptr [ecx],ecx 
003E2850 call  5ACBC87E  ; On return, EAX = 0x00000001. 
003E2855 mov   dword ptr [ebp-9Ch],eax 
003E285B cmp   dword ptr [ebp-9Ch],0 
003E2862 setne  al 
003E2865 movzx  eax,al 
003E2868 mov   dword ptr [ebp-64h],eax 
003E286B cmp   dword ptr [ebp-64h],0 
003E286F jne   003E289C 

ऊपर मशीन कोड लिस्टिंग से है, .NET फ्रेमवर्क के NGEN मॉड्यूल, 4.5 संस्करण द्वारा उत्पन्न , मैं निम्नलिखित निष्कर्ष निकालता हूं।

  1. रिक्त स्ट्रिंग के खिलाफ समानता शाब्दिक और System.String वर्ग पर स्थिर string.Empty संपत्ति के लिए

    परीक्षण, सभी व्यावहारिक उद्देश्यों के लिए, समान। दो कोड स्निपेट्स के बीच एकमात्र अंतर पहला कदम निर्देश का स्रोत है, और दोनों डीएस के सापेक्ष ऑफ़सेट हैं, जिसका अर्थ यह है कि दोनों बेक्ड-इन स्थिरांक का संदर्भ देते हैं।

  2. रिक्त स्ट्रिंग के खिलाफ समानता, के रूप में या तो एक शाब्दिक या string.Empty संपत्ति के लिए

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

  3. स्ट्रिंग की लंबाई का परीक्षण करना एक-तर्क फ़ंक्शन कॉल सेट करता है, जो 1 (रजिस्टर ईएक्स में) देता है, जो परीक्षण की स्ट्रिंग की लंबाई होती है।

  4. यह देखते हुए कि तुरंत दिखाई मशीन कोड लगभग समान है, एकमात्र कारण है कि मैं कल्पना कर सकते हैं कि स्टिंग लंबाई हाकी द्वारा रिपोर्ट से अधिक स्ट्रिंग समानता के बेहतर प्रदर्शन के लिए खाते हैं कि दो तर्क समारोह जो कि निष्पादन करता है वह एक-तर्क फ़ंक्शन से काफी बेहतर अनुकूलित होता है जो स्ट्रिंग उदाहरण की लंबाई को पढ़ता है।

निष्कर्ष

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

यह अभ्यास स्ट्रिंग के साथ तुलना करने की लागत के बारे में किसी भी चिंता के लिए हो सकता है, अगर कोई हो, तो या मेरे सहायक वर्गों द्वारा निरंतर परिभाषित किया गया है।

हालांकि, यह इसे बदलने के लिए एक परेशान सवाल भी उठाता है; स्ट्रिंग के विरुद्ध तुलना क्यों कर रहा है। स्ट्रिंग की लंबाई का परीक्षण करने से अधिक कुशल? या क्या शिनि द्वारा उपयोग किया जाने वाला परीक्षण अवैध है क्योंकि लूप लागू किया गया है? (मुझे लगता है कि विश्वास करने के लिए मुश्किल है, लेकिन, तो फिर, मैं पहले भी मूर्ख बनाया गया है, के रूप में मुझे यकीन है कि तुम हो रहा हूँ!)

मैं लंबे समय से मान लिया है कि System.String वस्तुओं की गिनती की गई तार, मूल रूप से लंबे समय तक स्थापित मूल स्ट्रिंग (बीस्ट्र) के समान है जिसे हम लंबे समय से COM से जानते हैं।

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

  • कोई संबंधित समस्या नहीं^_^