Autor |
Beitrag |
walter_b
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: Mi 16.07.08 12:04
Hallo zusammen
Welches ist die optimalste Anwendung, um einem String hinten einen anderen anzuhängen? Ich möchte meinem String gerne 14 Nullen anhängen. Und ich habe mich gefragt, welche der verschiedenen Möglichkeiten die schnellste ist:
Delphi-Quelltext 1:
| str:= str+'00000000000000'; |
oder
Delphi-Quelltext 1:
| Insert('0000000000000', str, 1000); |
Oder gibt es eine bessere Lösung? Vielen Dank.
|
|
Fabian E.
      
Beiträge: 554
Windows 7 Ultimate
Visual Studio 2008 Pro, Visual Studion 2010 Ultimate
|
Verfasst: Mi 16.07.08 12:16
Mit Insert kannst du als letzten Parameter den Index angeben wo der String eingefügt werden soll.
Da musst du halt die Länge der ursprünglichen Strings angeben.
|
|
walter_b 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: Mi 16.07.08 12:21
Und wenn ich die Länge nicht kenne, da sie variabel ist?
Und welche der beiden Varianten ist optimaler?
|
|
Fabian E.
      
Beiträge: 554
Windows 7 Ultimate
Visual Studio 2008 Pro, Visual Studion 2010 Ultimate
|
Verfasst: Mi 16.07.08 12:22
Die Länge kann man über Length() herrausfinden.
|
|
Jerk
      
Beiträge: 251
Vista Ultimate, Ubuntu
Turbo Delphi 2006
|
Verfasst: Mi 16.07.08 12:37
Ich würd die erste benutzen, da brauch man nich wissen wie Lang der String is.
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 16.07.08 12:45
Moin!
walter_b hat folgendes geschrieben: | Welches ist die optimalste Anwendung, um einem String hinten einen anderen anzuhängen? Ich möchte meinem String gerne 14 Nullen anhängen. Und ich habe mich gefragt, welche der verschiedenen Möglichkeiten die schnellste ist: |
Von der Geschwindigkeit her sollte es bei sowas eigentlich egal sein, Probleme gibt es bei diesen "Aktionen" aber an einer anderen Stelle: beim Speicherverbrauch!
Das ist ist üblicherweise unkritisch:
walter_b hat folgendes geschrieben: | Delphi-Quelltext 1:
| str:= str+'00000000000000'; | |
Du solltest nur nicht die Nullen einzeln an den String anfügen, da dann unverhältnismäßig viel Speicher belegt wird.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 16.07.08 12:47
Je nach dem, wie Du den String aufbaust, kann es aber auch durch Speicher-Zugriffe recht schnell erledigt werden. Voraussetzung dafür ist jedoch, dass Du die entgültige Länge des Strings im Vorhinein kurz berechnen kannst.
In dem Fall kann man nämlich auch das in der Form bauen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| var S: String; PS: ^PChar absolute S; L : Integer; begin L := SetLength(S, L); Inc(PS, L - 14); FillChar(PS^, '0', 14); Inc(PS, 14);
end; |
Zur Erklärung: Durch das Vorausberechnen der Länge erspart man sich das ständige Realloziieren des Stringpuffers.
Alternativ sieht man häufig auch, dass der String auf eine viel größere Länge initialisiert wird, als wirklich benötigt und im Nachhinein auf die eigentliche Länge reduziert wird. Effekt ist ähnlich der Vorgehensweise wie das Vorausberechnen der Länge, jedoch mit dem Unterschied, dass zwei Aufrufe des Speichermnagers notwendig sind, jedoch mit dem Vorteil, dass diese Methode auch mit nicht im Vorhinein bekannten Längenangaben funktioniert, sofern man die maximal mögliche Länge nach OBEN abschätzen kann.
@Narses: Der Speicherverbrauch ist etwa das Doppelte des Resultierenden Strings (incl. Padding). Problematisch ist eher die Speicherfragmentierung, die den Speichermanager unnötig lahm macht.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Zuletzt bearbeitet von BenBE am Mi 16.07.08 12:51, insgesamt 2-mal bearbeitet
|
|
walter_b 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: Mi 16.07.08 12:48
Ach so, okee, danke. Aber wegen der Auswirkung: Wenn das 1 Mia mal durchgeführt wird (und das wird es!), dann könnte da ein kleiner Effekt vielleicht doch grössere Auswirkungen haben, deshalb habe ich gefragt.
|
|
Boldar
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: Mi 16.07.08 14:19
ich würde das so lösen:
Delphi-Quelltext 1:
| a:= concat (s1, '0000000000'); |
Dass ist glaube ich die schnellste Variante
|
|
nagel
      
Beiträge: 708
Win7, Ubuntu 10.10
|
Verfasst: Mi 16.07.08 15:53
Laut Delphi-Hilfe ist + schneller als Concat.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 16.07.08 16:10
Und + ist langsamer als direkt im String zu arbeiten ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
walter_b 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: Mi 16.07.08 20:31
Habe noch festgestellt, dass ich
+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0 schreiben muss, anstelle der 14 Nullen, da ich Null-Bytes brauche und nicht Nullen. Oder gibt es einen eleganteren Weg dafür?
|
|
Yogu
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: Mi 16.07.08 20:52
Nehm doch anstatt von '0' die zwei Zeichen #0 - dann wird das Zeichen zum ASCII-Code 0 eingefügt.
------------------------------------------
Du hast es anscheinend schon selbst herausgefunden.
Eleganter könnte es evlt. so gehen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| var Len: Integer; begin Len := Length(S); SetLength(S, Len+14); FillChar(S[Len+1], 14, #0); end; |
|
|
walter_b 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: Mi 16.07.08 21:04
Wenn ich ehrlich bin: Eleganz ist mir egal. Welches ist von der Geschwindigkeit her schneller?
|
|
Fabian E.
      
Beiträge: 554
Windows 7 Ultimate
Visual Studio 2008 Pro, Visual Studion 2010 Ultimate
|
Verfasst: Mi 16.07.08 21:57
|
|
Boldar
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: Mi 16.07.08 23:01
|
|
walter_b 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: Do 17.07.08 16:55
BenBE hat folgendes geschrieben: | Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| var S: String; PS: ^PChar absolute S; L : Integer; begin L := SetLength(S, L); Inc(PS, L - 14); FillChar(PS^, '0', 14); Inc(PS, 14);
end; | |
Hab es Ausprobiert. Funktioniert Soweit auch, jedoch wird mir nach FillChar(PS^, '0', 14); und Inc(PS, 14); die Variabeln S und Wort gelöscht. Hier mein Skript:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| var S: String; PS: ^PChar absolute S; L : Integer;
[...]
writeln(wort); L:=14; SetLength(S, L); S:=Wort; writeln(wort); writeln(s); Inc(PS, L - 14); writeln(s); FillChar(PS^, 14, '0'); Inc(PS, 14); writeln(S); writeln(wort); |
Die Ausgaben dazwischen: A, A, A, A, *nichts*, 0 (und beim nächsten Durchgang ist Wort plötzlich 1.)
Edit: kann ich auch anstelle von 0 einen Null-byte reinsetzen? #0 akzeptiert er nicht.
|
|
Boldar
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: Do 17.07.08 17:08
Delphi-Quelltext 1:
| FillChar(PS^, 14, chr(0)); |
|
|
walter_b 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: Do 17.07.08 17:44
Okee, jetzt ist zwar das mit dem Null-byte da, aber die Variabeln werden mir immernoch gelöscht. Warum das? Was läuft hier falsch?
|
|
walter_b 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: Do 17.07.08 19:48
Ich habe jetzt das Skript von Yogu ausprobiert, doch auch hier läuft etwas schief.
Folgendes ist der Code:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| Len := Length(Wort); SetLength(Wortchen, Len+14); wortchen:=Wort; writeln(Len); FillChar(wortchen[Len+1], 14, 'g' ); writeln(wortchen); |
Diese Werte werden ausgegeben:
Len bei den ersten 10 Durchgängen 1 (richtig so)
Bei wortchen geht er dem Alphabet nach (so wie es das Programm vorschreiben würde). Doch wieso setzt er das G nicht? Ersetze ich diese Zeile durch
Delphi-Quelltext 1:
| FillChar(wortchen[Len], 14, 'g' ); |
dann habe ich immer an der ersten Stelle ein g, während der rest normal weitergeht. Aber wieso ignoriert er die 14?
|
|