21. marts 2004 - 15:02Der er
13 kommentarer og 1 løsning
CompareString ghastg\ighed
Hejsa
Findes der ikke en anden metode til at sammenligne 2 strings efter de samme regler som gaelder for COmpareString, men som er hurtigere. Er der nogen der eventuelt kender steder paa nettet, hvor jeg kan finde ud af mere?
Nu er CompareStr skrevet i kropsnært assembler så det burde være så optimeret som det kan være:
function CompareStr(const S1, S2: string): Integer; assembler; asm PUSH ESI ; 1 clock cycle PUSH EDI ; 1 clock cycle MOV ESI,EAX ; 4 clock cycles MOV EDI,EDX ; 4 clock cycles OR EAX,EAX ; Sæt evt. zero-flag JE @@1 ; Jump @@1 hvis zero = 1 MOV EAX,[EAX-4] ; Ryk en tand @@1: OR EDX,EDX ; Sæt evt. zero-flaget JE @@2 ; jump even til @@2 MOV EDX,[EDX-4] ; Ryk en tand @@2: MOV ECX,EAX CMP ECX,EDX JBE @@3 MOV ECX,EDX @@3: CMP ECX,ECX REPE CMPSB ; tager ca. 8-10 clock cycles JE @@4 MOVZX EAX,BYTE PTR [ESI-1] MOVZX EDX,BYTE PTR [EDI-1] @@4: SUB EAX,EDX POP EDI POP ESI end;
.. og jeg husker ikke ret meget af den slags længere. En løselig vurdering af instruktionerne får mig dog til at tro, at det ikke kan blive meget bedre. Mon ikke flaskehalsen ligger andetsteds?
Hvis data er til det, kan du generere en streng-signatur som kun fylder eks. 1/10 af strengen, men hvorved man hurtigt kan bestemme om strengen er større eller mindre eller lig med streng2. Den såkaldte "store once, use often approach".
Mht. flaskehalsen: Hvis du sorterer en liste af en slags, kan det være, at at du trigger en OnChange event hver gang du bytter rundt på to elementer - og så tager det pludselig lang tid!
Bruger du BeginUpdate og EndUpdate når du opererer på dine data?
Så vidt jeg kan se, så gør de det samme. CompareString har flere options:
NORM_IGNORECASE: Ignore case. NORM_IGNOREKANATYPE: Do not differentiate between Hiragana and Katakana characters. Corresponding Hiragana and Katakana characters compare as equal. NORM_IGNORENONSPACE: Ignore nonspacing characters. NORM_IGNORESYMBOLS: Ignore symbols. NORM_IGNOREWIDTH: Do not differentiate between a single-byte character and the same character as a double-byte character. SORT_STRINGSORT: Treat punctuation the same as symbols.
mens CompareStr er lidt mere hardcore. Den sammenligner to strenge og enten er de ens eller så er de forskellige.
Begge funktioner returnerer -1,0,1 så det skulle være det samme.
CSTR_LESS_THAN The string pointed to by the lpString1 parameter is less in lexical value than the string pointed to by the lpString2 parameter.
CSTR_EQUAL The string pointed to by lpString1 is equal in lexical value to the string pointed to by lpString2.
CSTR_GREATER_THAN The string pointed to by lpString1 is greater in lexical value than the string pointed to by lpString2.
Funktionen har desuden mulighed for at begrænse antallet af karakterer. Man kan f.eks. vælge at sammenligne på de første 5 tegn.
Her kører Borlands funktion videre og i Worst-Case, hvor strengene er ens, fortsætter den altså strengen ud. I Best-Case bliver kun det første tegn undersøgt.
CompareString findes i Kernel32, og der er stor chance for at dll'en er hentet ind i hukommelsen. Her burde der altså heller ikke være stor ventetid.
Du burde i dit eksempel ikke have baseret tidstagnigen på gettick count ... jeg kan ikek huske, om du gør det, men ulempen ved det er, at den afrunder til hvert 10 milisekunder. Det er selvfølgelig bare et spørgsmål om at at addere flere linier til filen.
Jeg kan desværre ikke give noget kode, men med dit eksempel har jeg da et lille eksperiment jeg kan arbejde videre med
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.