2010-01-22 21 views
12

bir dize karşılaştırma vs karşılaştırmak nedir? dize güvenli olmayan işaretçi karşılaştırma kullanacağı örnekte karşılaştırırlarkenBir GUID ne kadar pahalı ve daha hızlı olurdu

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

:

bool same=(Guid)Identifier==id; 

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

test etmek için yeterince kolay değil mi? –

+3

benzer (ama aynı değil) soru burada http://stackoverflow.com/questions/713109/performance-using-guid-object-or-guid-string-as-key –

+2

Ne zaman, bu, ne zaman olurdu? Bu, her ne pahasına olursa olsun kaçınılması gereken bir mikro optimizasyon olgusuna benziyor. Unutmayın, önce işin yapılmasını (gerekirse) daha hızlı yapmasını sağlayın. –

cevap

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(); 

Ve farklı değerler için bu sonucu (en iyi senaryo) aldı:

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! 

Ve aynı değere (kötü senaryo)

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 
için bu sonucu
+1

Bu gerçekten bir referans noktası gösterdiği için en iyi cevaptır ... –

+1

Karşılaştırma ölçütünüz, en iyi efor olan bayt 1 karşılaştırmasından çıkar. Daha fazla bayt karşılaştırırsanız, zamanlar daha da fazla farklılık gösterir. Ancak zaman farklılığı, istediğiniz gibi .ToString() öğesini de dahil ettiğiniz için, istediğiniz kadar büyük değil. string a = victim.ToString(); dize b = target.ToString(); (int i = 0; i <10000000; i ++) { bool equal = String.Equals (a, b, StringComparison.OrdinalIgnoreCase); } –

+0

@Mikael, güzel ipuçları; öneriniz string.equals performansında büyük bir iyileşme sağlar. –

1

Bir GUID gibi bir kod kullanacak ==. Bunu benchmarking olmadan

, ben Guid daha hızlı olacaktır şüpheli ama marjinal söz ediyoruz. Ve gerçekten de çok milyonlara yapılan karşılaştırmaların sayısını önemli ölçüde arttırmanız gerekiyor. bu da hızını etkileyecektir böylece

Hem karşılaştırmalar, soldan sağa anlam, erken kıracak. Karşılaştırma dizesi, karşılaştırma yapılmadan önce daha fazla denetime sahiptir ve bir başka yöntem de çağırır.

+0

bunu daha güvenli yapan nedir? – zsharp

+0

daha hızlı, daha güvenli olmadığını söyledi, ancak bir vakaya duyarlı olmayan dizge karşılaştırmasının bir işaretçi karşılaştırmasını nasıl kullanabileceğini merak etmekteydim. –

+0

"Güvensiz" anahtar kelimesinin kullanılması güvenli olmadığı anlamına gelmez, ancak C++ uygulamasında olduğu gibi bellek işaretçileri kullanmanıza olanak tanır. .Net çerçevesindeki birçok işlev bu şekilde uygulanır. Yani her iki yönde Ben sadece çerçevesinde fiili işlevine bakın :) kullanmak aynı derecede güvenli - özel statik güvensiz int CompareOrdinalIgnoreCaseHelper (string strA, dize STRB) –

1

GUID karşılaştırması 16 baytlık bir memcmp'dir. Bir dizgenin karşılaştırmasından daha kötü olmaz, ancak performansı önemsiyorsanız, yönetilen kod kullanılmamalı. Dize dizeli karşılaştırma VS düz bir UUID-UUID karşılaştırma yaparak benim testlerde

+0

Onun dize karşılaştırması büyük/küçük harfe duyarlıdır. Karşılaştırma, zaman açısından çok farklı olmamasına rağmen, bir Guid gibi bir byte-byte karşılaştırması olmaz. –

+0

Değil. Net guid Int32 + Int16 + Int16 + (bayt * 8) içerir. Ve son bayra kadar bir diğerine karşı karşılaştırır. En çok 11 karşılaştırma anlamına geliyor. –

+0

Yönetilen kod aslında oldukça hızlı - C++ 'dan yaklaşık% 25-50 daha yavaş kontrol ettim, Java ile aynı şekilde ... Python/Ruby için% 8,000 daha yavaş ve PHP için% 50,000 daha yavaş ... –

10

, UUID karşılaştırma Dize karşılaştırma yaklaşık 1/4 zaman alır. Bununla birlikte, String-> UUID'nin dökümü pahalıdır. UUID-> String dönüşümünden çok daha pahalı. Her ikisi de karşılaştırma yöntemlerinden daha pahalıdır.

Yani: Eğer var ise iki Uuıdlerin doğrudan UUIDs karşılaştırın. İki Diziniz varsa Dizeleri doğrudan karşılaştırın. Tek bir Dize ve bir UUID varsa, UUID'yi bir String'e dönüştürün ve Dizeleri karşılaştırın.

Bu kodu kullanılan
1

.NET Guid, bir dize olarak temsil edildiğinde bu biçimde biçimlendirilecek olan bir 16 baytlık yapıdır "xxxxxxxx-xxxx- xxxx-xxxx-xxxxxxxxxxxx "yaklaşık 32 karakterdir.

Yani 32 * 2 = 64 bayt alacak bir dize olarak temsil 16 bayt ve götürecek bir GUID olarak temsil etti.

GUID.Equals() daha iyi performans göstermelidir.

Ayrıca

GUID.Equals (GUID) eski katılan hiçbir boks yoktur guid1 == guid2 çünkü o zaman daha iyi performans gösterecektir.

+1

'Guid.Equals (nesne, nesne)' böylece un/kutulu olacaksınız; lütfen, benim referans noktası –

+0

Guid.Equals (Guid) burada açıklanmıştır bakın. http://msdn.microsoft.com/en-us/library/asw89aw8.aspx. Bu aşırı yüklenme için boks yok gibi görünüyor. – Santhosh

+0

oh üzgünüm, statik versiyondan bahsediyorsunuz; ama, her zaman, Guid.Equals (object) kullanmanız gerekir. Bütün nokta, –

İlgili konular