long t1 = DateTime.Now.Ticks; for(int i = 0; i < REP; i++) { // kald metode 1 } long t2 = DateTime.Now.Ticks; long t3 = DateTime.Now.Ticks; for(int i = 0; i < REP; i++) { // kalde metode 2 } long t4 = DateTime.Now.Ticks;
class MainClass { private const int REP = 10000000; public static bool meta(string tmp) { int res = int.Parse(tmp); if (res == 1) return true; else return false; } public static bool metb(string tmp) { if (tmp.Equals("1")) return true; else return false; }
public static bool metc(string tmp) { if (tmp == "1") return true; else return false; }
public static void Print(string desc, long t1, long t2) { Console.WriteLine(String.Format("{0} : {1:0.00}", desc, (t2 - t1)/10000000.0)); }
public static void Test(string s) { long t1 = DateTime.Now.Ticks; for(int i = 0; i < REP; i++) { meta(s); } long t2 = DateTime.Now.Ticks; Print("parse and ==", t1, t2); long t3 = DateTime.Now.Ticks; for(int i = 0; i < REP; i++) { metb(s); } long t4 = DateTime.Now.Ticks; Print("equals", t3, t4); long t5 = DateTime.Now.Ticks; for(int i = 0; i < REP; i++) { metc(s); } long t6 = DateTime.Now.Ticks; Print("==", t5, t6); }
Ja det kunne være rart at vide... Så skal man nok bruge den som passer bedst ind i applikationen. Jeg regner med at i min app så evalurer den true 95% af tiden, så skal jeg vel bruge '=='.
Jeg synes a I var lige gode om det, så md_craig smid lige også et svar.
Evaluating: (1 = 1) using Equals, time elapsed: 296,875 Evaluating: (1 = 1) using "==", time elapsed: 187,5 Evaluating: (1 = 20) using Equals, time elapsed: 250 Evaluating: (1 = 20) using "==", time elapsed: 359,375 Evaluating: (1 = 2500) using Equals, time elapsed: 250 Evaluating: (1 = 2500) using "==", time elapsed: 359,375 Evaluating: (1 = 23456) using Equals, time elapsed: 250 Evaluating: (1 = 23456) using "==", time elapsed: 359,375 Evaluating: (1 = 789022) using Equals, time elapsed: 250 Evaluating: (1 = 789022) using "==", time elapsed: 343,75 Evaluating: (20 = 1) using Equals, time elapsed: 250 Evaluating: (20 = 1) using "==", time elapsed: 343,75 Evaluating: (20 = 20) using Equals, time elapsed: 296,875 Evaluating: (20 = 20) using "==", time elapsed: 187,5 Evaluating: (20 = 2500) using Equals, time elapsed: 265,625 Evaluating: (20 = 2500) using "==", time elapsed: 359,375 Evaluating: (20 = 23456) using Equals, time elapsed: 250 Evaluating: (20 = 23456) using "==", time elapsed: 343,75 Evaluating: (20 = 789022) using Equals, time elapsed: 265,625 Evaluating: (20 = 789022) using "==", time elapsed: 343,75 Evaluating: (2500 = 1) using Equals, time elapsed: 265,625 Evaluating: (2500 = 1) using "==", time elapsed: 343,75 Evaluating: (2500 = 20) using Equals, time elapsed: 250 Evaluating: (2500 = 20) using "==", time elapsed: 343,75 Evaluating: (2500 = 2500) using Equals, time elapsed: 312,5 Evaluating: (2500 = 2500) using "==", time elapsed: 171,875 Evaluating: (2500 = 23456) using Equals, time elapsed: 250 Evaluating: (2500 = 23456) using "==", time elapsed: 359,375 Evaluating: (2500 = 789022) using Equals, time elapsed: 250 Evaluating: (2500 = 789022) using "==", time elapsed: 343,75 Evaluating: (23456 = 1) using Equals, time elapsed: 265,625 Evaluating: (23456 = 1) using "==", time elapsed: 343,75 Evaluating: (23456 = 20) using Equals, time elapsed: 265,625 Evaluating: (23456 = 20) using "==", time elapsed: 343,75 Evaluating: (23456 = 2500) using Equals, time elapsed: 250 Evaluating: (23456 = 2500) using "==", time elapsed: 359,375 Evaluating: (23456 = 23456) using Equals, time elapsed: 328,125 Evaluating: (23456 = 23456) using "==", time elapsed: 187,5 Evaluating: (23456 = 789022) using Equals, time elapsed: 250 Evaluating: (23456 = 789022) using "==", time elapsed: 359,375 Evaluating: (789022 = 1) using Equals, time elapsed: 250 Evaluating: (789022 = 1) using "==", time elapsed: 343,75 Evaluating: (789022 = 20) using Equals, time elapsed: 250 Evaluating: (789022 = 20) using "==", time elapsed: 343,75 Evaluating: (789022 = 2500) using Equals, time elapsed: 265,625 Evaluating: (789022 = 2500) using "==", time elapsed: 343,75 Evaluating: (789022 = 23456) using Equals, time elapsed: 265,625 Evaluating: (789022 = 23456) using "==", time elapsed: 359,375 Evaluating: (789022 = 789022) using Equals, time elapsed: 312,5 Evaluating: (789022 = 789022) using "==", time elapsed: 187,5
Det kunne have givet mig fint mening hvis der var forskel på True/False evaluering ved længere strenge end 1 og det var til falses side...
da den ene metode kunne være tvunget igennem hele strengen mens den anden kun var tvunget en del af vejen... (til første ukorekte char)...
Men det her giver som sagt ikke umiddelbart mening... Og derfor må der som arne_v siger være lige så store chancer for at der er mange andre faktorer spiller ind...
[C#] public static bool operator ==( string a, string b );
...
Remarks This operator is implemented using the Equals method, which means the comparands are tested for a combination of reference and value equality. The comparison is case-sensitive.
Jeg tror jeg kan komme med en forklaring på hvorfor == er hurtigere end Equals. Hvad I ikke har taget højde for er at string classen er immutable og derfor kan være implementeret ved at to strenge der indeholder det samme rent faktisk er samme objekt.
Det vil sige at == operatoren med høj sandsynlighed er implementeret ved først at se om de to objekter rent faktisk er samme objekt (som jeg tror den gør). Når de er ens vil der derfor ikke være nogen reel strengsammenligning. Det vil der være hvis de er forskellige.
Jeg tror at I kan komme ud over denne sammenligning af objekter, ved at oprette strengene vha. new String("bla")
Det huer mig ikke at du faktisk har ret... der har det sQ modeleret det underligt hvis man spørg mig, aner man ikke lægnere hvornår man har ens referencer eller ej, i og med at selv om man laver to nye strings som fx:
string a = "test"; string b = "test";
at så har de pluselig samme reference, dette burde så resultere i at hvis man ændre a, så slår det igennem for b også... men nej... så bliver der endelig alokeret en y på heapen... Tror det er sådan noget man bare ikke skal tænke over når man så programmere ellers får man dårlige nerver.. men det er naturligvis for at spare hukommelse, kunne bare forestille mig det gnaver lidt på ydelsen når man så asigner i og med den skal igennem hele heapen for at se om der skulle være en tilsvarende streng...
Der er ikke noget underligt i at de folder konstanter sammen. Det gør de fleste andre sprog også.
string a = "test"; string b = "test";
laver et konstant objekt og lader 2 referencer pege på det samme.
Java og C++ gør helt det samme.
Og ja - det er tilsyneladende det som giver forskelllen.
Jeg kan ikke helt se logikken i at == opfører sig anderledes end Equals - og slet ikke når dokumentationen siger at == kalder Equals, men sådan er der så meget.
arne_v: at Equal og == ikke er implementeret ens er vel bare en "feature" i frameworket. Men det forklarer hvorfor ens strenge (objekter) sammenlignes hurtigere end forskellige strenge.
md_craig: At du ikke kan ændre i en streng, må du bare finde dig i. og være opmærksom på at hver gang du prøver at ændre i en streng, oprettes der nye objekter.
Implemented using er vel heller ikke det samme som at de er ens?
Generelt er jeg lidt bange for at overskrive "==" operatoren, fordi jeg synes det kan være med til at forvirre om hvad der rent faktisk sker... er det indholdet der bliver sammenlignet, eller er det objekterne... Måske er det bare fordi jeg stadig tænker Java en gang imellem ;)
Tja... normalt vil == jo evaluere på referencer, dvs hvad der ligger i stacken, mens Equals evaluere på hvad der ligger i heapen, men hvis man holder sig til at man i c# kan evaluere de datatyper der samtidig er keywords, så går du jo ikke gal.
Normalt ville man jo mene at ValueTypes burde være dem der kunne evalueres med == mes Reference types med equals... men sådan er det ikke 100% åbenbart... desuden ved jeg heller ikke om du vil kunne evaluere Structs med == ??... Structs er jo defineret som e "custom" value type... Enums også med i lidt samme kategori...
2 ting jeg mest har styr på brugen af frem for implementeringen af..
Kommentar: arne_v 08/04-2005 10:38:55
Nu kender jeg ikke så meget til Java eller C++, er undervist i java og der fik vi i sin tid at vide at når du asigner en string sker der det samme som hvis du kaldte dens constructor, det er jo i så fald ikke helt rigtigt så?
C# supporterer jo operator overload så == kan kalde en Equals, hvis programmøren vil.
----
Java:
public void m() { String a = "test"; String b = "test"; ... }
svarer også mere til:
private final static String TEST = "test"; public void m() { String a = TEST; String b = TEST; ... }
----
mono String == tester iøvrigt tilsyneladende ikke på samme objekt:
C:\>csc /optimize+ compare2.cs Microsoft (R) Visual C# .NET Compiler version 7.10.6001.4 for Microsoft (R) .NET Framework version 1.1.4322 Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.