Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - vorteile von static arrays gegenüber dynamic arrays


Fred Ferkel - Di 03.06.03 14:44
Titel: vorteile von static arrays gegenüber dynamic arrays
hi

wie groß ist der unterschied ob ich

Delphi-Quelltext
1:
2:
3:
4:
array[0..10of byte
oder
array of byte
setlength(,10)

verwende?

mfg Sven

ps: wenn ich 100 dynamische habe wäre es besser nur einen großen zu haben?


Simon Joker - Di 03.06.03 15:23

Dynamische verwendest du, wenn du vorher nicht weist wie lang das Array werden soll. Wenn du das aber weist, dann verwende Statische.

Viele kleine oder einen Großen? Hmm für jedes Array brauchts eine Speicheradresse, von der aus du die Daten liest dabei werden Blöcke gelesen, die der Definition des Array entsprechen. Für viele Array hast du halt mehr AdressPointer, absonst bleibt es sich gleich.


Fred Ferkel - Di 03.06.03 16:22

ich mein der array soll zeichenketten/zahlen enthalten; es wäre nicht negativ für das prog die zeichenkettenlänge auf 100 zubeschränken aber

Delphi-Quelltext
1:
array[0..100]                    

ist schlechter als

Delphi-Quelltext
1:
setlength(,100)                    

wenn daneben auch sehr oft setlength(,4) etc. kommt...


tommie-lie - Di 03.06.03 18:21

Das Problem mit dynamischen Arrays ist nur, daß das Speichermanagement von Borland/Microsoft den speicher nicht wieder freigibt, wenn mit SetLength ein Array vergrößert wurde und dieses mangels Platz in eine größere, ausreichende Speicherlücke verschoben wird. Dabei bleibt also der alte Speicher für andere Programme belegt und wenn man oft das Array vergrößert, könnte man u.U. anderen Programmen (wir erinnern uns, seit 8 Jahren gibt's Multitasking ;-) ) den Speicher abgraben. Hast du also vor, öfters die Länge des dynamischen Arrays zu verändern, solltest du vorher überschlagen/ausrechnen, welche Größe du am Ende haben wirst. Wenn du zum Beispiel weißt, das eine Schleife 10mal läuft und sie das Array um eins verlängert, lieber vorher um 10 verlängern und dann in die Felder schreiben.
Performancemäßig gibt es soweit ich weiß keinen Unterschied, bis eben auf das Speicherproblem, was man wiederum mit alternativen Speichermanagern lösen kann (wobei alle mir bekannten dafür andere Haken haben).


Fred Ferkel - Di 03.06.03 18:40

bist du sicher?? ich hab zwar nicht so den plan aber im taskmanager zumindest ist davon nüscht zu sehn...
außerdem bleibt der array zumindest bei mir immer an derselben stelle

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
  x:array of byte;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
  i:integer;
begin
  caption:=inttostr(integer((@x)));
  for i:=1 to 100 do
    setlength(x,length(x)+1);
end;



Moderiert von user profile icontommie-lie: Code- durch Delphi-Tags ersetzt


tommie-lie - Di 03.06.03 21:03

Fred Ferkel hat folgendes geschrieben:
bist du sicher??

Da ich kein NT habe, konnte ich es selber noch nicht zuverlässig ausprobieren, aber hier [http://www.delphipraxis.net/viewtopic.php?p=23214#23214], hier [http://www.delphi-forum.de/viewtopic.php?p=44621#44621] und hier [http://www.optimalcode.com/memmgr.htm] sind ein paar Sachen zum Thema.


Fred Ferkel - Di 03.06.03 21:34

verdammt, gestern war meine array-welt noch in ordnung :(
(acuh wenn sich das bei meinem beispiel im augenblick nicht bestätigt)

bei dem gelinkten beispiel klappts: 4164KB bzw. ca. 390000KB wo er dann anfing auszulagern
----------------------
bei integerarray:2980=2980
bei stringarray:2976=2976

das problem scheint nur bei komplexen typen wie Tobject aufzutreten?
nachtrag:
die adresse von allen verwendeten arrays scheint gleichzubleiben was nur 2 rückschlüsse zulässt
1. die adreese von allen verwendeten arrays bleibt gleich
2. ich bin zu blöd die adresse des arrays zu ermitteln und auszugeben aber der debugger gibt mir auch recht...


tommie-lie - Di 03.06.03 21:55

Fred Ferkel hat folgendes geschrieben:
verdammt, gestern war meine array-welt noch in ordnung :(

So schnell kann's gehen :mrgreen:


Zitat:
das problem scheint nur bei komplexen typen wie Tobject aufzutreten?

Normalerweise nicht. Irgendwo (ich dachte das wär auf den verlinkten Seiten, war wohl doch nicht so :roll:) gab's das Beispiel auch mit einem String, der ständig um ein Zeichen verlängert wurde -> das gleiche Ergebnis.


Zitat:
nachtrag:
die adresse von allen verwendeten arrays scheint gleichzubleiben was nur 2 rückschlüsse zulässt
1. die adreese von allen verwendeten arrays bleibt gleich
2. ich bin zu blöd die adresse des arrays zu ermitteln und auszugeben aber der debugger gibt mir auch recht...

kompilierst du das:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.Button1Click(Sender: TObject);
var
  x, y: array of Byte;
begin
  SetLength(x, 100);
  SetLength(y, 100);
  Caption := inttostr(integer(@x)) + '---' + inttostr(integer(@y));
end;

Die Caption lautet bei mir: "6878124---6878120" (auf Wunsch mit Screenshot beweisbar!).
Also entweder, mein System zählt nicht so wie ich, oder die Adressen sind nicht die absoluten Speicheradressen.
Da mein Computer bisher immer das gemacht hat, was ich wollte (naja, außer wenn er mal nicht das gemacht hat, was ich wollte...), denke ich eher, daß zweiteres der Fall sein wird, also wäre dien Versuch die Speicheradresse auf diese Art und Weise zu holen vollkommen für die Katz'. ;-)


Fred Ferkel - Di 03.06.03 22:32

wieso?? *schmunzel*
mit alt+F5 kann man die adressen ja auch anzeigen lassen
@x=$12F9F0
@x[0]=$BE326C
@x[99]=$BE32CF

@y=$12F9EC
@y[0]=$BE32DC
@y[99]=$BE333F

@x[0] bis @x[99]= 100Byte
@y[0] bis @y[99]= ach wird schon stimmen

was sind dann @x/@y? vielleicht 32bit-zeiger auf x[0]?
@x[0]=$BE326C=12464748
x=12464748


ohne worte


tommie-lie - Di 03.06.03 22:58

:autsch:
Naja, wie dem auch sei (:mrgreen:), angeblich sind dynamische Arrays, die sehr oft verlängerst werden ebenso speicherschädlich wie LongStrings, mit denen das gleiche mehrmals geschieht, das habe ich wiederholt gelesen, auch wenn ich es nie nachprüfen konnte (NT kommt mir nich auf den Rechner!), so glaube ich doch den Leuten, die mehr Ahnung haben als ich und sich die Mühe machen, einen alternativen Speichermanager zu schreiben.


Fred Ferkel - Di 03.06.03 23:14

solnage mein byte-array klarkommt isst auch für mich alles ok^^


Delete - Mi 04.06.03 01:39

tommie-lie hat folgendes geschrieben:
Dabei bleibt also der alte Speicher für andere Programme belegt

Nicht fuer andere, nur fuer dein eigenes. Jedes Programm hat unter 32-Bit Windows einen Adressraum von 2 GB zur Verfuegung und wenn es sich den selber zu gemuellt hat, ist Schluss.


Motzi - Mi 04.06.03 08:02

Ein dyn. Array ist nur ein Zeiger auf den dyn. allozierten Speicherblock. Mit @DynArray bekommst du also nur die Adresse des Zeigers, nicht aber die des Speicherblocks! Um an die Adresse des Speicherblocks zu kommen musst du @DynArray[0] verwenden... Das Problem bei dyn. Arrays und Strings (die intern eigentlich auch nix andres als dyn. Arrays sind) ist, dass bei jeder Längenänderung der Speicher realloziert werden muss...


Fred Ferkel - Mi 04.06.03 15:49

Zitat:
Ein dyn. Array ist nur ein Zeiger auf den dyn. allozierten Speicherblock. Mit @DynArray bekommst du also nur die Adresse des Zeigers, nicht aber die des Speicherblocks! Um an die Adresse des Speicherblocks zu kommen musst du @DynArray[0] verwenden...


genau das hatte ich doch oben gezeigt ;)

1:
@Motzi: du sagt z.B: das bei jeder längenänderung dies geschieht, ist das auch bei verkürzungen der fall?

2:
dann lohnt es sich ja garnicht einen array zu verkürzen wenn man teile nicht mehr benötigt, ich bastle gerade an einer tabelle die ich für ein andere projekt benötige und da verwende ich für jede zelle eine edit, ich würde natürlich nur soviele edits haben wie zu sehen sind, aber was wenn der user maximiert? dann würde ich ja wieder mehr benötigen, gibt es da eine speichertechnische alternative zum array die sich hier anbeiten würde?


Fred Ferkel - Mi 04.06.03 22:13

also beim verkleinern wird nicht reallociert, nur beim vergrößern


AndyB - Mi 04.06.03 23:18

Fred Ferkel hat folgendes geschrieben:
also beim verkleinern wird nicht reallociert, nur beim vergrößern

Es wird auch beim Verkleinern der Speicher realloziert.


Fred Ferkel - Do 05.06.03 00:41

naja also ich hab festgestellt das die adresse des 1. items gleichbleibt beim verkürzen des arrays (integer und Tobject arrays)


AndyB - Do 05.06.03 10:09

Natürlich bleibt die Adresse gleich, da der Speicherbereich, den das Array belegt, auch für das verkürzte Array genug Platz bietet. Und warum sollte ein komplett neuer Speicher reserviert, die Daten kopiert und der alte Speicher freigegeben werden, wenn man das ganz auch einfach durch eine Verkleinerung des Speicherbereichs erreichen kann.

Aus diesem Grund ist es auch besser vorerst mehr Speicher als wirklich nötig (worst case) zu reservieren und dann den nicht benötigten Speicher wieder freizugeben, als für jedes zusätzliche Element das Array um eins zu vergrößern.


Fred Ferkel - Di 10.06.03 00:11

hi

kriegt es einer von euch gebacken diesen memory manager zu benutzen?
http://www.optimalcode.com/memmgr.htm

ich nämlich nicht und auf der seite sind keine FAQs/Tuts/Beispiele und auf mails antworten die schon garnicht...

thx


AndyB - Di 10.06.03 00:32

Was ist daran so schwer zu installieren?

Du fügst die Unit als aller erste im Projektquellcode ein. Fertig.


Fred Ferkel - Di 10.06.03 03:04

hehe ok, ich hatte nur die methode mit der ichs überprüfen wollte verhunzt ^^