Avatar billede justincase1089 Nybegynder
21. marts 2004 - 15:02 Der 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?

Justin Case
Avatar billede doc404 Novice
21. marts 2004 - 18:28 #1
Er det CompareStr eller CompareStrings i TString?
Avatar billede hrc Mester
21. marts 2004 - 20:59 #2
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".
Avatar billede hrc Mester
21. marts 2004 - 21:03 #3
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?
Avatar billede justincase1089 Nybegynder
22. marts 2004 - 14:13 #4
Det er
function CompareString; external kernel32 name 'CompareStringA'; jeg bruger nu

er CompareStr hurtigere ... jeg mener den er jo defineret direkte i Delphi i ASM, men gør den det samme ?
Avatar billede hrc Mester
22. marts 2004 - 14:57 #5
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.
Avatar billede hrc Mester
22. marts 2004 - 15:04 #6
CompareStiring returnerer:

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.
Avatar billede borrisholt Novice
23. marts 2004 - 21:06 #7
justincase1089>> Må vi ikke se dit projekt ?

Jens B
Avatar billede borrisholt Novice
23. marts 2004 - 21:43 #8
Det er ikke i sammenligning af tekst strenge der tager tid det er noget andet.

Jeg kan sammen ligne 20878 tekst strenge på typisk 15 millisekunder.

Jeg har lagt mit lille eksperiment her ; http://borrisholt.com/eksperten/sameText.zip

Jens B
Avatar billede borrisholt Novice
29. marts 2004 - 13:48 #9
justincase1089>> Der er sq ikke meget gang i dig ?

Jens B
Avatar billede justincase1089 Nybegynder
30. marts 2004 - 09:03 #10
Sorry .....

Ok, med dit sidste svar må du være en kandidat Jens ... svar please
Avatar billede borrisholt Novice
30. marts 2004 - 09:05 #11
Jooe tak det er meget godt .. Men jeg fandt aldrig ud af hvad dit problem var ?

Jens B
Avatar billede justincase1089 Nybegynder
30. marts 2004 - 09:05 #12
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
Avatar billede borrisholt Novice
30. marts 2004 - 09:07 #13
Jeg baserede mit kode på GetTickCount, fordi jeg regnede med det tog lang tid, men det gjorde det ikke. Så den nøjagtige tidsangivelse er uintressant.

Jens B
Avatar billede justincase1089 Nybegynder
28. april 2004 - 15:50 #14
Tak
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester