2010-01-22 3 views
12

was wäre schneller?Wie teuer ist ein GUID-Cast und Vergleich gegen einen String-Vergleich

bool same=(Guid)Identifier==id; 

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

ist nicht einfach genug zu testen? –

+3

ähnliche (aber nicht die gleiche) Frage hier http://stackoverflow.com/questions/713109/performance-using-guid-object-or-guid-string-as-key –

+2

Wann, je, wäre das wichtig? Das klingt wie ein Fall von Mikro-Optimierung, die um jeden Preis vermieden werden sollte. Denken Sie daran, zuerst machen Sie es, als (wenn nötig) es schneller machen. –

Antwort

26

ich diesen Code verwendet:

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

Und bekam dieses Ergebnis für verschiedene Werte (bestes Szenario):

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! 

Und dieses Ergebnis für denselben Wert (schlimmeres Szenario)

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

Dies ist die beste Antwort, da es tatsächlich einen Benchmark zeigt ... –

+1

Ihr Benchmark beendet den Vergleich auf Byte 1, was der beste Aufwand ist. Wenn Sie noch mehr Bytes vergleichen, würden die Zeiten noch mehr abweichen. Aber die Zeit diff ist nicht so groß wie Sie behaupten, da Sie die .ToString() in die Schleife aufgenommen haben. Zeichenfolge a = opfer.ToString(); Zeichenfolge b = target.ToString(); für (int i = 0; i <10000000; i ++) { bool gleich = String.Equals (a, b, StringComparison.OrdinalIgnoreCase); } –

+0

@Mikael, nette Tipps; Ihr Vorschlag führte zu einer enormen Verbesserung der Leistung von string.equals. –

1

A Guid == Guid Code wie verwenden:

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

während die Zeichenfolge in Ihrem Beispiel vergleichen, werden einen unsicheren Zeiger Vergleich verwenden.

Ohne Benchmarking, ich vermute, die Guid wird schneller sein, aber wir reden marginal. Und Sie müssen wirklich die Anzahl der Vergleiche zu den Multi-Millionen, um es wichtig zu machen.

Beide Vergleiche werden früh ausbrechen, also von links nach rechts, so dass auch die Geschwindigkeit beeinflusst wird. Der Zeichenfolgenvergleich enthält mehr Prüfungen, bevor der Vergleich stattfindet, und einen weiteren Methodenaufruf.

+0

Was macht es sicherer? – zsharp

+0

sagte er schneller, nicht sicherer, obwohl ich neugierig wäre, zu sehen, wie ein Stringvergleich ohne Berücksichtigung der Groß- und Kleinschreibung einen Zeigervergleich verwenden könnte. –

+0

Das Schlüsselwort "unsafe" ist nicht unbedingt unsicher zu verwenden, aber Sie können Speicherzeiger wie in C++ verwenden. Viele Funktionen im .Net-Framework sind auf diese Weise implementiert. So sind in beide Richtungen gleichermaßen sicher zu verwenden :) ich nur auf die eigentliche Funktion im Rahmen verweisen - private static int unsicher CompareOrdinalIgnoreCaseHelper (string strA, string strB) –

1

Ein GUID-Vergleich ist ein Memcmp von 16 Bytes. Es ist nicht schlimmer als ein String-Vergleich, aber wenn Sie Wert auf Leistung legen, sollten Sie keinen verwalteten Code verwenden.

+0

Sein String Vergleich ist Groß-und Kleinschreibung. Während der Vergleich in Bezug auf die Zeit nicht viel anders sein sollte, ist es kein Byte-für-Byte-Vergleich wie ein Guid. –

+0

Es ist nicht. Die .NET-GUID besteht aus Int32 + Int16 + Int16 + (Bytes * 8). Und es vergleicht eins bis zum letzten Byte. Bedeutet ein Maximum von 11 Vergleichen. –

+0

Verwalteter Code ist eigentlich ziemlich schnell - ungefähr 25-50% langsamer als C++, das ich zuletzt überprüft habe, ungefähr das gleiche wie Java ... vergleiche das mit 8.000% langsamer für Python/Ruby und 50.000% langsamer für PHP ... –

10

In meiner Prüfung, die einen direkten UUID-UUID-Vergleich VS String-String-Vergleich durchführt, dauert der UUID-Vergleich etwa 1/4 der Zeit als der String-Vergleich.

Allerdings ist das Gießen von String-> UUID teuer. Viel teurer als die UUID-> String-Konvertierung. Beide sind teurer als die beiden Vergleichsmethoden.

So: Wenn Sie zwei UUIDs haben, vergleichen Sie die UUIDs direkt. Wenn Sie zwei Strings haben, vergleichen Sie die Strings direkt. Wenn Sie eine Zeichenfolge und eine UUID haben, konvertieren Sie die UUID in einen String und vergleichen Sie die Strings.

1

.NET Guid ist eine 16-Byte-Struktur, die, wenn sie als String dargestellt wird, in diesem Muster formatiert wird "xxxxxxxx-xxxx- xxxx-xxxx-xxxxxxxxxxxx "was ungefähr 32 Zeichen ist.

So dargestellt als eine GUID würde es 16 Bytes und als eine Zeichenfolge dargestellt würde es 32 * 2 = 64 Bytes dauern würde.

Also GUID.Equals() sollte besser funktionieren.

Auch GUID.Equals (GUID) würde besser funktionieren als guid1 == guid2, weil es keinen Boxing in ersterem gibt.

+1

'Guid.Equals (Objekt, Objekt)' so dass Sie un/Boxen beteiligt haben; Bitte, siehe meine Benchmark dort –

+0

Guid.Equals (Guid) wird hier beschrieben. http://msdn.microsoft.com/en-us/library/asw89aw8.aspx. Sieht so aus, als wäre für diese Überladung kein Boxing involviert. – Santhosh

+0

Oh, Entschuldigung, ich dachte du sprichst von einer statischen Version; aber, sowieso, müssen Sie Guid.Equals (Objekt) verwenden, wie der ganze Punkt über das Gießen von Objekt –

Verwandte Themen