Entwickler-Ecke
Algorithmen, Optimierung und Assembler - Explode-Funktion optimieren
n-regen - So 28.02.10 19:30
Titel: Explode-Funktion optimieren
Hallo!
Ich habe mir gerade eine Funktion gebastelt, die einen String anhand eines Trennzeichens in drei Teile zerlegt, eventuelle Anführungszeichen an Anfang und Ende der Teilstrings entfernt und diese dann als record zurückgibt.
Kann man die Funktion noch irgendwie schneller machen?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| type TExplodedString = record value1:string; value2:string; value3:string; end;
function explode(inputstr, separator: string):TExplodedString; var ps,dest: integer; begin dest := 0; result.value1 := ''; result.value2 := ''; result.value3 := ''; for ps := 1 to length(inputstr) do begin if inputstr[ps] = separator then inc(dest) else begin case dest of 0: result.value1 := result.value1 + inputstr[ps]; 1: result.value2 := result.value2 + inputstr[ps]; 2: result.value3 := result.value3 + inputstr[ps]; end; end; end; if result.value1[1] = '"' then begin result.value1 := copy(result.value1, 2, length(result.value1)-2); result.value2 := copy(result.value2, 2, length(result.value2)-2); result.value3 := copy(result.value3, 2, length(result.value3)-2); end; end; |
F34r0fTh3D4rk - So 28.02.10 19:43
Ungetestet, aber so oder so ähnlich könnte es gehen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| type TExplodedString = array[0..2] of string;
function explode(inputstr, separator: string):TExplodedString; var i, p: integer; exstr: string; begin for i := 0 to 2 do begin p := pos(inpustr, separator); exstr[i] := copy(inputstr, 1, p-1); inputstr := copy(inputstr, p+length(separator)); end; return exstr; end; |
Gibt es sowas wie
NextPos() in Delphi?
jaenicke - So 28.02.10 19:48
F34r0fTh3D4rk hat folgendes geschrieben : |
Gibt es sowas wie NextPos() in Delphi? |
Meinst du
POSEX?
F34r0fTh3D4rk - So 28.02.10 19:51
Delphi scheint leider nicht so eine tolle API zu haben wie Java*, deshalb hab ichs auf die Schnelle nicht gefunden ;)
Dann ist es ungefähr so (ungetestet):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| function explode(inputstr, separator: string):TExplodedString; var i, p, last: integer; exstr: TExplodedString; begin last = 1; for i := 0 to 2 do begin p := posex(inpustr, separator, last); exstr[i] := copy(inputstr, 1, p-1); last := p+length(separator); end; result := exstr; end; |
*String [http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html], ja OOP ist schon was feines ;)
EDIT: return durch
result := ersetzt.
BenBE - So 28.02.10 19:59
Wenn zuwenige Trennzeichen enthalten ist, gibt Copy nen Leerstring zurück für den letzten Teilstring
n-regen - So 28.02.10 21:02
So, ich habe
F34r0fTh3D4rks Vorschlag von halb-C nach Delphi übersetzt und überarbeitet:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| function TForm1.explode(inputstr, separator: string):TExplodedString; var i, p, last: integer; begin last := 1; for i := 0 to 1 do begin p := posex(separator, inputstr, last); result[i] := copy(inputstr, last, p-last); last := p+length(separator); end; result[2] := copy(inputstr, last, length(inputstr)-(last-1)); if result[0][1] = '"' then begin result[0] := copy(result[0], 2, length(result[0])-2); result[1] := copy(result[1], 2, length(result[1])-2); result[2] := copy(result[2], 2, length(result[2])-2); end; end; |
Die Funktion ist zwar immer noch (oder schon wieder) ziemlich langsam, aber sie funktioniert.
Vielen Dank euch allen!
F34r0fTh3D4rk - So 28.02.10 21:08
Sry wegen der fremdartigen Syntax :lol: , aber ich benutze seit Jahren kein Delphi mehr ;)
Eine Frage: Wozu ist das?
Delphi-Quelltext
1: 2: 3: 4: 5:
| if result[0][1] = '"' then begin result[0] := copy(result[0], 2, length(result[0])-2); result[1] := copy(result[1], 2, length(result[1])-2); result[2] := copy(result[2], 2, length(result[2])-2); end; |
Und was hat es mit dem
'"' aufsich?
n-regen - So 28.02.10 21:26
Der Teil soll Anführungszeichen am Anfang und Ende der Teilstrings rausfiltern.
Man könnte ihn auch noch verkürzen:
Delphi-Quelltext
1: 2: 3: 4:
| if result[0][1] = '"' then begin for i := 0 to 2 do result[i] := copy(result[i], 2, length(result[i])-2); end; |
Ach ja:
' leitet einen String ein.
'"' ist also ein String, der nur ein Anführungszeichen enthält.
dummzeuch - So 28.02.10 21:49
n-regen hat folgendes geschrieben : |
Der Teil soll Anführungszeichen am Anfang und Ende der Teilstrings rausfiltern.
Man könnte ihn auch noch verkürzen:
Delphi-Quelltext 1: 2: 3: 4:
| if result[0][1] = '"' then begin for i := 0 to 2 do result[i] := copy(result[i], 2, length(result[i])-2); end; |
|
Ohne jetzt den restlichen Code genauer analysiert zu haben: Bist Du sicher, dass Result[0] niemals ein Leerstring sein kann? Wenn doch, knallt das da:
Delphi-Quelltext
1:
| if result[0][1] = '"' then |
twm
F34r0fTh3D4rk - So 28.02.10 22:42
n-regen hat folgendes geschrieben : |
Ach ja: ' leitet einen String ein. '"' ist also ein String, der nur ein Anführungszeichen enthält. |
Ich weiß wie Strings in Delphi funktionieren :). Ich habe mich nur gewundert, was etwas so spezielles in einer allgemeinen
explode Methode zu suchen hat.
Kha - So 28.02.10 22:47
F34r0fTh3D4rk hat folgendes geschrieben : |
Ich habe mich nur gewundert, was etwas so spezielles in einer allgemeinen explode Methode zu suchen hat. |
Eine allgemeine Explode-Funktion mit exakt drei Output-Einträgen :mrgreen: ? Das mit den Anführungszeichen hätte ich heute aber
gut gebrauchen [
http://projecteuler.net/project/words.txt] können ;) ...
n-regen - Mo 01.03.10 01:30
dummzeuch hat folgendes geschrieben : |
Ohne jetzt den restlichen Code genauer analysiert zu haben: Bist Du sicher, dass Result[0] niemals ein Leerstring sein kann? Wenn doch, knallt das da:
Delphi-Quelltext 1:
| if result[0][1] = '"' then | |
Das könnte wirklich problematisch werden.
Welche Alternative ist da schneller?
Delphi-Quelltext
1:
| if (result[0][1] <> '') and (result[0][1] = '"') then |
(Delphi würde doch nach dem ersten Vergleich aufhören, wenn er FALSE zurückgibt, oder?)
oder
Delphi-Quelltext
1:
| if pos('"', result[0][1]) = 1 then |
aksdb - Mo 01.03.10 02:36
Spricht denn was dagegen, eine TStringList mit .Delimiter und .DelimitedText zu benutzen?
jfheins - Mo 01.03.10 10:29
aksdb hat folgendes geschrieben : |
Spricht denn was dagegen, eine TStringList mit .Delimiter und .DelimitedText zu benutzen? |
Ja - die Geschwindigkeit ;)
Guck mal in die DP, da wurde sowas schonmal "durchoptimiert"
http://www.delphipraxis.net/topic98278,0,asc,0.html ;)
F34r0fTh3D4rk - Mo 01.03.10 12:03
n-regen hat folgendes geschrieben : |
dummzeuch hat folgendes geschrieben : | Ohne jetzt den restlichen Code genauer analysiert zu haben: Bist Du sicher, dass Result[0] niemals ein Leerstring sein kann? Wenn doch, knallt das da:
Delphi-Quelltext 1:
| if result[0][1] = '"' then | | Das könnte wirklich problematisch werden.
Welche Alternative ist da schneller?
Delphi-Quelltext 1:
| if (result[0][1] <> '') and (result[0][1] = '"') then | (Delphi würde doch nach dem ersten Vergleich aufhören, wenn er FALSE zurückgibt, oder?)
oder
Delphi-Quelltext 1:
| if pos('"', result[0][1]) = 1 then | |
Ich glaube, bevor man sich solche Fragen stellen muss, sollte man sich den Rest seines Codes nochmal genau angucken, um ausschließen zu können, dass die Geschwindigkeitsbremse nicht doch ganz woanders liegt. Wie es aussieht hast du ja nur vor, einen String in drei Teile zu zerlegen. Das wird nur dann zu einem Zeitproblem, wenn du das sehr häufig machst. Was ist der genaue Kontext, in dem du deine Funktion verwendest? Vielleicht lässt sich da einiges mehr herausholen.
tif - Mo 01.03.10 12:32
Versteckt in der Unit HttpUtil gibt's noch (zumindest bei/ab 2009)
Delphi-Quelltext
1:
| function StringToStringArray(const str: string; const delim: string): TStringDynArray; |
Ob die schneller ist weiss ich nicht, aber sie dampft den Quelltext auf eine Zeile ein.
Viel Erfolg
Tino
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!