2010-01-22 10 views
12

कितनी महंगा है जो तेजी से होगा?एक GUID कास्ट और तुलना एक स्ट्रिंग तुलना बनाम

bool same=(Guid)Identifier==id; 

bool same=String.Equals(string1,string2, StringComparison.OrdinalIgnoreCase); 
+4

परीक्षण करने के लिए पर्याप्त आसान नहीं है? –

+3

समान (लेकिन वही नहीं) प्रश्न यहां http://stackoverflow.com/questions/713109/performance-using-guid-object-or-guid-string-as-key –

+2

जब कभी, यह बात होगी? यह माइक्रो ऑप्टिमाइजिंग के मामले की तरह लगता है, जिसे हर कीमत से बचा जाना चाहिए। याद रखें, पहले इसे (यदि आवश्यक हो) से अधिक काम करें, इसे तेज़ी से बनाएं। –

उत्तर

26

मैं इस कोड का इस्तेमाल किया:

object victim = Guid.Empty; 
Guid target = Guid.NewGuid(); 

Stopwatch sw = new Stopwatch(); 
sw.Start(); 
for (int i = 0; i < 10000000; i++){ 
    bool equal = ((Guid) victim) == target; 
} 
Console.WriteLine("Direct cast : {0}", sw.Elapsed); 

sw.Reset(); sw.Start(); 
for (int i = 0; i < 10000000; i++) 
{ 
    bool equal = Guid.Equals(victim, target); 
} 
Console.WriteLine("Guid.Equals : {0}", sw.Elapsed); 

sw.Reset(); sw.Start(); 
string a = victim.ToString(); // as suggested by Mikael 
string b = target.ToString(); 
for (int i = 0; i < 10000000; i++) 
{ 
    bool equal = String.Equals(a, b, StringComparison.OrdinalIgnoreCase); 
} 
Console.WriteLine("String.Equals : {0}", sw.Elapsed); 

Console.ReadLine(); 

और विभिन्न मूल्यों के लिए इस परिणाम (सबसे अच्छा परिदृश्य) मिल गया:

object victim = Guid.Empty; 
Guid target = Guid.NewGuid(); 
// Direct cast : 00:00:00.1164198 
// Guid.Equals : 00:00:02.1268147 
// String.Equals : 00:00:00.4129527 // oh my! 

और एक ही मूल्य (बदतर परिदृश्य)

object victim = Guid.Empty; 
Guid target = Guid.Empty; 
// Direct cast : 00:00:00.2793173 
// Guid.Equals : 00:00:03.5625948 
// String.Equals : 00:00:01.7564302 
के लिए इस परिणाम
+1

यह सबसे अच्छा जवाब है क्योंकि यह वास्तव में एक बेंचमार्क दिखाता है ... –

+1

आपका बेंचमार्क बाइट 1 पर तुलना से बाहर निकलता है जो सबसे अच्छा प्रयास है। यदि आप और भी बाइट्स की तुलना करते हैं तो समय और भी अलग होगा। लेकिन समय सीमा भिन्न है जितना आप दावा करते हैं, क्योंकि आपने लूप में .ToString() शामिल किया है। स्ट्रिंग ए = पीड़ित। टॉस्ट्रिंग(); स्ट्रिंग बी = target.ToString(); (int i = 0; i <10000000; i ++) { बूल बराबर = स्ट्रिंग। एक्वाल्स (ए, बी, स्ट्रिंग कॉम्परिसन। ऑर्डिनल इग्नोरकेस); } –

+0

@ मिकाएल, अच्छी टिप्स; आपके सुझाव स्ट्रिंग.equals प्रदर्शन पर एक बड़ा सुधार का नेतृत्व करते हैं। –

1

एक GUID == Guid की तरह कोड का उपयोग करेगा: जबकि स्ट्रिंग अपने उदाहरण में तुलना एक असुरक्षित सूचक तुलना का उपयोग करेगा

public bool Equals(Guid g) 
{ 
if (g._a != this._a) 
{ 
    return false; 
} 
if (g._b != this._b) 
{ 
    return false; 
} 

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

दोनों तुलना जल्दी ही टूट जाएंगी, जिसका मतलब बाएं से दाएं है, जिससे गति भी प्रभावित होगी। तुलना करने से पहले स्ट्रिंग तुलना में अधिक जांच होती है और एक और विधि कॉल भी होती है।

+0

क्या यह सुरक्षित बनाता है? – zsharp

+0

उन्होंने कहा, तेज़, सुरक्षित नहीं, हालांकि मैं यह देखने के लिए उत्सुक हूं कि केस-असंवेदनशील स्ट्रिंग तुलना एक सूचक तुलना का उपयोग कैसे कर सकती है। –

+0

"असुरक्षित" कीवर्ड उपयोग करने के लिए आवश्यक रूप से असुरक्षित नहीं है, लेकिन यह आपको सी ++ में मेमोरी पॉइंटर्स का उपयोग करने की अनुमति देता है। नेट फ्रेमवर्क में कई फ़ंक्शन इस तरह कार्यान्वित किए जाते हैं। तो दोनों तरीकों से समान रूप से :) मैं केवल ढांचे में वास्तविक समारोह का उल्लेख उपयोग करने के लिए सुरक्षित कर रहे हैं - निजी स्थिर असुरक्षित पूर्णांक CompareOrdinalIgnoreCaseHelper (स्ट्रिंग Stra, स्ट्रिंग STRB) –

1

एक GUID तुलना 16 बाइट्स का एक memcmp है। यह स्ट्रिंग तुलना की तुलना में बदतर नहीं होगा, लेकिन यदि आप प्रदर्शन के बारे में परवाह करते हैं तो आपको प्रबंधित कोड का उपयोग नहीं करना चाहिए।

+0

उनकी स्ट्रिंग तुलना केस-असंवेदनशील है। जबकि तुलना समय के मुकाबले बहुत अलग नहीं होनी चाहिए, यह एक बाइट-बाइट तुलना नहीं है जैसे कि गुइड होगा। –

+0

यह नहीं है। .Net guid में Int32 + Int16 + Int16 + (बाइट्स * 8) शामिल हैं। और यह आखिरी बाइट तक दूसरे के खिलाफ तुलना करता है। अधिकतम 11 तुलनाओं का मतलब है। –

+0

प्रबंधित कोड वास्तव में बहुत तेज़ है - सी ++ की तुलना में लगभग 25-50% धीमी है, मैंने जावा के समान ही जांच की है ... तुलना करें कि पाइथन/रूबी के लिए 8,000% धीमी है और PHP के लिए 50,000% धीमी है ... –

10

मेरे परीक्षण में सीधे यूयूआईडी-यूयूआईडी तुलना वीएस स्ट्रिंग-स्ट्रिंग तुलना करने से, यूयूआईडी तुलना स्ट्रिंग तुलना के रूप में लगभग 1/4 समय लेती है।

हालांकि, स्ट्रिंग-> यूयूआईडी का कास्टिंग महंगा है। UUID-> स्ट्रिंग रूपांतरण से अधिक महंगा। दोनों तुलनात्मक तरीकों की तुलना में अधिक महंगा हैं।

तो: यदि आपके पास दो यूयूआईडी यूयूआईडी की तुलना सीधे करते हैं। यदि आपके पास दो स्ट्रिंग्स स्ट्रिंग्स की तुलना सीधे तुलना करते हैं। यदि आपके पास एक स्ट्रिंग और एक यूयूआईडी है, तो यूयूआईडी को स्ट्रिंग में कनवर्ट करें और स्ट्रिंग्स की तुलना करें।

1

.NET Guid एक 16 बाइट संरचना है जो एक स्ट्रिंग के रूप में प्रतिनिधित्व करते समय इस पैटर्न में स्वरूपित किया जाएगा "xxxxxxxx-xxxx- xxxx-xxxx-xxxxxxxxxxxx "जो लगभग 32 वर्ण है।

तो GUID के रूप में प्रतिनिधित्व किया गया है, इसमें 16 बाइट्स और एक स्ट्रिंग के रूप में प्रतिनिधित्व किया जाएगा जिसमें 32 * 2 = 64 बाइट्स लगेगा।

तो GUID.Equals() बेहतर प्रदर्शन करना चाहिए।

इसके अलावा GUID.Equals (GUID) बेहतर प्रदर्शन करेगा तो guid1 == guid2 क्योंकि पूर्व में कोई मुक्केबाजी शामिल नहीं है।

+1

'Guid.Equals (ऑब्जेक्ट, ऑब्जेक्ट) 'तो आपके पास अन/मुक्केबाजी शामिल होगी; कृपया, मेरे बेंचमार्क को वहां देखें –

+0

Guid.Equals (Guid) यहां वर्णित है। http://msdn.microsoft.com/en-us/library/asw89aw8.aspx। ऐसा लगता है कि इस अधिभार के लिए कोई मुक्केबाजी शामिल नहीं है। – Santhosh

+0

ओह क्षमा करें, मैंने सोचा कि आप स्थिर संस्करण के बारे में बात कर रहे हैं; लेकिन, वैसे भी, आपको Guid.Equals (ऑब्जेक्ट) का उपयोग करने की आवश्यकता होगी क्योंकि पूरे बिंदु ऑब्जेक्ट –

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