Autor Beitrag
walter_b
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: 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:

ausblenden Delphi-Quelltext
1:
str:= str+'00000000000000';					


oder

ausblenden Delphi-Quelltext
1:
Insert('0000000000000', str, 1000); // Wie kann ich hier markieren, dass er ans Ende soll?					


Oder gibt es eine bessere Lösung? Vielen Dank.
Fabian E.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 554

Windows 7 Ultimate
Visual Studio 2008 Pro, Visual Studion 2010 Ultimate
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: 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.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 554

Windows 7 Ultimate
Visual Studio 2008 Pro, Visual Studion 2010 Ultimate
BeitragVerfasst: Mi 16.07.08 12:22 
Die Länge kann man über Length() herrausfinden.
Jerk
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 251

Vista Ultimate, Ubuntu
Turbo Delphi 2006
BeitragVerfasst: Mi 16.07.08 12:37 
Ich würd die erste benutzen, da brauch man nich wissen wie Lang der String is.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 16.07.08 12:45 
Moin!

user profile iconwalter_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! :shock:

Das ist ist üblicherweise unkritisch:
user profile iconwalter_b hat folgendes geschrieben:
ausblenden 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. :idea:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
    S: String;
    PS: ^PChar absolute S; //Nur tun, wenn man weiß, was man tut!
    L : Integer;
begin
    L := {...} //Berechnen
    SetLength(S, L);
    //Daten in den String füllen
    Inc(PS, L - 14); //PS zum Befüllen nutzen; am Ende sollte er 14 Zeichen vor dem Stringende stehen...

    FillChar(PS^, '0'14); //14 Nullen anhängen
    Inc(PS, 14);

    //S enthält nun den vollständigen String ...
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Mi 16.07.08 14:19 
ich würde das so lösen:
ausblenden Delphi-Quelltext
1:
a:= concat (s1, '0000000000');					


Dass ist glaube ich die schnellste Variante
nagel
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 708

Win7, Ubuntu 10.10

BeitragVerfasst: Mi 16.07.08 15:53 
Laut Delphi-Hilfe ist + schneller als Concat.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: 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. :idea:

------------------------------------------

Du hast es anscheinend schon selbst herausgefunden.

Eleganter könnte es evlt. so gehen:

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: Mi 16.07.08 21:04 
Wenn ich ehrlich bin: Eleganz ist mir egal. Welches ist von der Geschwindigkeit her schneller?
Fabian E.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 554

Windows 7 Ultimate
Visual Studio 2008 Pro, Visual Studion 2010 Ultimate
BeitragVerfasst: Mi 16.07.08 21:57 
user profile iconwalter_b hat folgendes geschrieben:
Oder gibt es einen eleganteren Weg dafür?


user profile iconwalter_b hat folgendes geschrieben:
Wenn ich ehrlich bin: Eleganz ist mir egal. Welches ist von der Geschwindigkeit her schneller?


:lol:

Ne aber probiers doch einfach aus was schneller ist ;)
Lass das ganze 1.000.000 mal laufen und guck was schneller war ;)
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Mi 16.07.08 23:01 
user profile iconYogu hat folgendes geschrieben:


Eleganter könnte es evlt. so gehen:

ausblenden 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;


Dass ist wohl definitiv der Schnellere Weg, da es "Hardwarenäher" ist
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: Do 17.07.08 16:55 
user profile iconBenBE hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
    S: String;
    PS: ^PChar absolute S; //Nur tun, wenn man weiß, was man tut!
    L : Integer;
begin
    L := {...} //Berechnen
    SetLength(S, L);
    //Daten in den String füllen
    Inc(PS, L - 14); //PS zum Befüllen nutzen; am Ende sollte er 14 Zeichen vor dem Stringende stehen...

    FillChar(PS^, '0'14); //14 Nullen anhängen
    Inc(PS, 14);

    //S enthält nun den vollständigen String ...
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:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Do 17.07.08 17:08 
ausblenden Delphi-Quelltext
1:
FillChar(PS^, 14, chr(0));					
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: 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:

ausblenden 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

ausblenden 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?