AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Schnellster Stringmatching-Algorithmus in ASM übersetzen
Thema durchsuchen
Ansicht
Themen-Optionen

Schnellster Stringmatching-Algorithmus in ASM übersetzen

Offene Frage von "Sereby"
Ein Thema von alzaimar · begonnen am 5. Dez 2007 · letzter Beitrag vom 3. Jul 2008
Antwort Antwort
Seite 2 von 8     12 34     Letzte »    
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#11

Re: Schnellster Stringmatching-Algorithmus in ASM übersetzen

  Alt 6. Dez 2007, 09:28
Gute Idee. Nur bei einem 1GB-String wird das mit dem Speicher dann ein wenig knapp...
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#12

Re: Schnellster Stringmatching-Algorithmus in ASM übersetzen

  Alt 6. Dez 2007, 09:34
Zitat von alzaimar:
@sirius: Mit direkten PChar in ASM zu arbeiten, würde nichts bringen? Wenn ich das in Delphi mache (in PChar umwandeln) kann ich mir die blöde Abfrage am Ende zwar sparen, dafür wird der Code aber um ein Vielfaches langsamer.

Kann man da gar nichts machen?

Und was meinst du mit 'Sprungtabelle hart codieren'?
Wo habe ich was von PChar geschrieben?

Ja, das hart codieren habe ich auch wieder verworfen, man könnte quasi das Array konstant mit 0 füllen und bei inc abfragen, das Array ander Stelle 0 ist. Ist aber totaler Blödsinn.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#13

Re: Schnellster Stringmatching-Algorithmus in ASM übersetzen

  Alt 6. Dez 2007, 09:38
Zitat von sirius:
Wo habe ich was von PChar geschrieben?
War darauf bezogen.
Zitat von sirius:
Viel Potenzial sehe ich auf Anhieb nicht.
War so'ne Idee von mir. Schließlich arbeiten die Performancegeier alle mit PChar, weil sie meinen, das das dann schneller wird.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#14

Re: Schnellster Stringmatching-Algorithmus in ASM übersetzen

  Alt 6. Dez 2007, 09:54
Mir gefällt String viel besser (weil da steht die Länge auch gleich "im" String)

Deine Optimierung...liegt die in dem c1 und dem cp?
Ab welcher Länge von substr siehst du da Vorteile?
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Progman

Registriert seit: 31. Aug 2007
Ort: 99974 MHL
695 Beiträge
 
Delphi 10.1 Berlin Starter
 
#15

Re: Schnellster Stringmatching-Algorithmus in ASM übersetzen

  Alt 6. Dez 2007, 10:01
Hat sich schonmal jemand die Function Pos (und ähnliche) im Originalcode angeschaut?
Die sind in Assembler. Also kann man da nichts mehr beschleunigen.
Karl-Heinz
Populanten von Domizilen mit fragiler, transparenter Aussenstruktur sollten sich von der Translation von gegen Deformierung resistenter Materie distanzieren!
(Wer im Glashaus sitzt sollte nicht mit Steinen werfen)
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#16

Re: Schnellster Stringmatching-Algorithmus in ASM übersetzen

  Alt 6. Dez 2007, 10:10
Hallo,
Zitat von Progman:
Hat sich schonmal jemand die Function Pos (und ähnliche) im Originalcode angeschaut?
Die sind in Assembler. Also kann man da nichts mehr beschleunigen.
also...
erstens ist die Pos-Funktion von Delphi ziemlich schlecht programmiert (oder haben die das inzwischen optimiert?), und zweitens kann ich Dir einen Assembler-Code schreiben, der für diese Funktion drei Tage braucht . alzaimar's Algorithmus ist sicher auch ohne Assembler wesentlich schneller (hat er ja auch geschrieben).

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#17

Re: Schnellster Stringmatching-Algorithmus in ASM übersetzen

  Alt 6. Dez 2007, 10:16
Zitat von Progman:
Die sind in Assembler. Also kann man da nichts mehr beschleunigen.
Es ist erwiesen, dass die original Version von Pos langsam ist. Und nur weil sie in ASM direkt codiert wurde heißt das nicht, dass man da nichst mehr optimieren und / oder verbessern könnte.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#18

Re: Schnellster Stringmatching-Algorithmus in ASM übersetzen

  Alt 6. Dez 2007, 10:18
@Sirius: Die Optimierung von Raita (und von mir) liegt darin, das man nicht jedesmal 'CompareMem' aufruft, sondern eben nur dann, wenn die ersten und letzten Zeichen übereinstimmen. Es gibt sogar noch eine Optimierung, die das letzte, das erste und das mittlere Zeichen vergleichen, und erst dann CompareMem aufrufen. Da hatte ich bei meinem Szenario (Tags in XML-Dateien finden) keinen Geschwindigkeitsvorteil.

Wenn ich das weglasse, also direkt CompareMem aufrufe, dauert das bei meinem Testprogramm 3x so lange. Aber ich gebe zu, der Suchstring ist 8 Zeichen lang.

Angeblich ist Boyer-Moore ja noch schneller, ich konnte das aber nicht verifizieren. Im Gegenteil, er ist aufgrund des Overheads in der Schleife doch langsamer (jedenfalls in Delphi).

Ich habe eben mal den Gewinner der FastCode-Challenge (Pos) eingebaut und selbst der Code ist 1,5x langsamer.

Bevor das hier ausartet, sollte ich gleich mal Folgendes sagen:

Der QuickSearch-Algorithmus spielt seine Stärken umso stärker aus, je länger der Suchtext ist. Weiterhin sollte der zu suchende Text nicht zu kurz sein, da der Overhead im Berechnen der Sprungtabelle sonst den Performancegewinn zunichte macht.

QS eignet sich also für lange Texte und Suchstrings mit mehr als 4 Zeichen. Wenn man QS also in seinem Code verwenden möchte, dann sollte man für kurze Strings (PI x Daumen: 1000 Zeichen) und Suchstrings mit weniger als 4 Zeichen zu dem FastCode-Pos greifen, ansonsten zum QS.

Übrigens verwendet man Stringmatching-Algorithmen bei der Suche nach Gensequenzen. Ich hatte das Problem, in mehreren MB großen XML-Strings nach bestimmten Tags zu suchen. Daher die Optimierung "erst erstes und letztes Zeichen vergleichen", denn das ist '<' und '>' und das kommt im XML ja relativ selten vor.

So wie ich das sehe, wird man nur marginal etwas herausholen können. Ich denke, ich poste heute abend mal ein verbessertes Pos, das den FCC-Gewinner und QS vereint.

@ProgMan: Nicht die Sprache ist entscheidend, sondern der Algorithmus. Selbst die POS-Funktion der RTL ist lahm, gegenüber dem Gewinner der Fastcode-Challenge (Faktor 3 ungefähr).
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#19

Re: Schnellster Stringmatching-Algorithmus in ASM übersetzen

  Alt 6. Dez 2007, 12:00
Delphi-Quellcode:
function QSString(const ssubstr,text:string):Integer;stdcall;
//Delphi fügt automatisch push ebp; mov ebp,esp; ein
asm
  push ebx //register retten
  push edi
  push esi

  mov eax,[ebp+8] //ssubbstr
  mov edx,[eax-4] //length(ssubstr)
  mov ebx,edx //ebx=length(ssubstr) (für später)
  sub edx,2 //edx=length(ssubstr)-2
  push edx //n2 = [ebp - 16] =length(ssubstr)-2
  movzx edx, byte ptr [eax]
  push edx //c1 = [ebp - 20] =ssubstr[1]
  movzx edx, byte ptr [eax+ebx-1]
  push edx //cp= [ebp - 24] =ssubstr[ length(ssubstr) ]


  mov cx,$0100 //array mit ebx=length(ssubstr)+1 füllen
  inc ebx
 @fillarray:
    push ebx
    dec cx
  jnz @fillarray
  dec ebx

  // For i := 0 To n-1 Do Skip[sSubStr[i]] := n - i;
  xor ecx,ecx
  mov edi,[ebp+8] //ssubstr
  push ebx //length(ssubstr) auf [esp] legen/retten
  mov esi,ebp
  sub esi,$41C //Zeiger auf Sprungtabelle
 @fillotherskip: //for i=ecx :=0 to ebx
    movzx eax, byte ptr [edi+ecx] //ssubstr[ecx+1] in eax
    mov [esi+eax*4],ebx //[sprungtabelle+xxx] := length(ssubstr)-i
    inc ecx
    dec ebx
  jnz @fillotherskip


  mov esi,[ebp+12] //Zeiger auf text

  mov ecx,[esi-4] //length(text) in ecx
  sub ecx,[esp] //ecx ist jetzt k (length(ssubstr) abgezogen)
  jle @endwhile //wenn k<=0 Schleife überspringen

  xor edi,edi //Zählvariable
  mov bl,[ebp-20] //c1 und
  mov bh,[ebp-24] //cp
  lea edx,[ebp-$41C] //Zeiger auf Sprungtabelle


  //in Schleife gilt:
  //edi ist Zähler i
  //esi ist Zeiger auf Text
  //ebx ist erster(bl) und letzter(bh) Char von substr
  //[esp] ist n (Länge von substr)
  //ecx ist k (Abbruchbedingung)
  //edx ist Zeiger auf Sprungtabelle

 @while:

    cmp [esi+edi],bl //Vergleich text[i] mit c1
    jnz @endif //wenn ungleich --> springen
    mov eax,[esp] //length(ssubstr) in eax
    add eax,edi //i addieren
    cmp [esi+eax-1],bh //Vergleich text[i+length(ssubstr)] mit cp
    jnz @endif

      cmp [esp],3 //length(ssubstr) mit 3 vergleichen
      jl @positiveExit //wenn kleiner 3 dann Ergebnis gefunden

      //comparemem
      push ecx //register retten
      push edx
      push edi
      push esi
      mov ecx,[ebp-16] //length(ssubstr)-2
      mov edx,ecx
      and edx,3
      add esi,edi
      inc esi
      mov edi,[ebp+8]
      inc edi
      shr ecx,2
      xor eax,eax
      repe cmpsd //Vergleich von DWORDs
      jne @endcmp
      mov ecx,edx
      repe cmpsb //Vergleich der restlichen Bytes
      jne @endcmp
      inc eax
     @endcmp:
      pop esi
      pop edi
      pop edx //register zurückholen
      pop ecx
      test al,al //Ergebnis von comparemem auswerten
      jnz @positiveExit

   @endif:
    mov eax,[esp] //length(ssubstr) nach eax
    add eax,edi //i dazuaddieren
    movzx eax, byte ptr [esi+eax] //test[i+length(ssubstr)+1]
    mov eax, [edx+eax*4] //Wert aus Sprungtabelle
    add edi, eax //..zu i dazuaddieren
    cmp edi, ecx //mit k vergleichen
  jle @while
 @endwhile:

  xor eax,eax //result:=0
  jmp @exit
@positiveExit:
  mov eax,edi //result:=i
  inc eax
@Exit:
  lea esp,ebp-12
  pop esi
  pop edi
  pop ebx
end;
Wenn ich mich nicht um +1 oder -1 mal verzählt habe, dürfte das stimmen.
Den letzten Absatz habe ich weggelassen.
Am meisten habe ich auf den Teil innerhalb der While-Schleife und darin außerhalb des IF-Blocks "optimiert".

Jetzt könnte man noch das cmp [esp],3 rausnehmen (weis nicht wieviel das bringt) und comparemem sozusagen als inline-Funktion reinschieben.
Aber erstmal testen, ob überhaupt alles richtig gemacht wird.

Edit: Fehler entfernt und Multiplikation entfernt
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#20

Re: Schnellster Stringmatching-Algorithmus in ASM übersetzen

  Alt 6. Dez 2007, 12:58
Klappt leider nicht.

Wenn der Suchstring im Text nicht vorhanden ist, geht das sauschnell. Nur leider findet er nix, auch wenn der Suchtext vorhanden ist, oder es kommt eine AV. Die AV kommt auch manchmal, wenn der Text nicht vorhanden ist.

Vermutlich irgendwas mit der Sprungtabelle.... Denk dran: Du kannst die Schleife nicht umdrehen:
For i := 1 To n Do Skip[sSubStr[i]] := n - i + 1; Wenn ein Buchstabe im Suchtext mehrmals vorkommt, dann wird das kleinste 'n-i+1' genommen. Daher muss(!) i hochgezählt werden ...
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 8     12 34     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:55 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz