Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi dynamische Arrays vergrößern (https://www.delphipraxis.net/135416-dynamische-arrays-vergroessern.html)

KahPee 10. Jun 2009 15:11


dynamische Arrays vergrößern
 
Hallo,
ich möchte einen dynamischen Array benutzen. Generell ist das kein Problem mit Setlength kann ich ja nun die Länge des Arrays angeben. Nun aber folgendes Problem. Zur Laufzeit soll sich der Array vergrößern, also hat der z.B. erst die Größe 1 und dann später kriegt er die Größe 2 weil dem Array ein neuer Wert hinzugefügt werden soll.
Wenn ich jetzt erneut das Setlenght ereignis aufgerufen wird, wird dann der erste Wert gelöscht? Das möchte ich nämlich verhindern! Ich möchte also, dass ich zur Laufzeit den Array immer weiter vergrößere, dass aber die zugewiesenen Werte erhalten bleiben..
Das Problem ist, dass theoretisch die Maximallänge des Arrays bei unendlich liegt, zu Laufzeit, soll das ganze immer weiter erhöht werden (Stück für Stück) da das Programm auch theoretisch unendlich lange läuft (bzw. bis der Arbeitsspeicher voll ist) hab ich natürlich einen Abbruch des Programms reingeschrieben.

mfg KahPee

jaenicke 10. Jun 2009 15:13

Re: dynamische Arrays vergrößern
 
Bei der Vergrößerung des Arrays wird der alte Inhalt kopiert, die Werte bleiben also erhalten.

In einer Schleife immer nur um eins vergrößern ist aber extrem langsam. Da ist dann ein Deltawert sinnvoll, so dass das Array immer gleich um 100 oder 1000 (je nach Anzahl) wächst.

KahPee 10. Jun 2009 15:15

Re: dynamische Arrays vergrößern
 
Ist das vergrößern, der Länge um 10 schneller als das Vergrößern der Länge 10mal um 1?

Vielen Dank schon mal für die Antowrt..

Luckie 10. Jun 2009 15:17

Re: dynamische Arrays vergrößern
 
Zitat:

Zitat von KahPee
Wenn ich jetzt erneut das Setlenght ereignis aufgerufen wird, wird dann der erste Wert gelöscht?

Ich mache daraus erstmal einen verständlichen Satz:
Zitat:

Wenn erneut Setlength aufgerufen wird, wird dann der erste Wert gelöscht?
Nein, wird es nicht. Warum auch? Überleg mal, wie brauchbar dann dynamische arrays wären, wenn das der Fall wäre. :roll:

Desweiteren hätte man sich diese Frage auch schnell durch ausprobieren beantworten können.

jaenicke 10. Jun 2009 15:18

Re: dynamische Arrays vergrößern
 
Zitat:

Zitat von KahPee
Ist das vergrößern, der Länge um 10 schneller als das Vergrößern der Länge 10mal um 1?

Ja, und je größer die Anzahl der Werte desto viel schneller ist das.

Der Grund ist, dass bei einer Vergrößerung jedesmal ein neuer Platz im Speicher reserviert und der alte Inhalt da hinkopiert wird. Und daher ist das auch arbeitsspeicherintensiv.

Deshalb vergrößere in größeren Schritte, je nach Anzahl der Werte in einer gewissen Zeit.

himitsu 10. Jun 2009 15:19

Re: dynamische Arrays vergrößern
 
wenn die Größe des Arrays geändert wird,
wird eine neues Array angelegt, der Inhalt kopiert, die alte Version gelöscht und der Zeiger zum neuen Array in die Variable eingetragen ... also mit jeder änderung wird das Array kopiert.

Wenn man da einen größeren Sprung nutzt, dann mußt nicht mehr bei jeder änderung das Array geändert/kopiert werden.

alzaimar 10. Jun 2009 15:41

Re: dynamische Arrays vergrößern
 
Zitat:

Zitat von KahPee
Ist das vergrößern, der Länge um 10 schneller als das Vergrößern der Länge 10mal um 1?

Zitat:

Zitat von Luckie
Desweiteren hätte man sich diese Frage auch schnell durch ausprobieren beantworten können.

:zwinker:

messie 10. Jun 2009 15:43

Re: dynamische Arrays vergrößern
 
Ich würde sagen, die Erhöhung der arrays hängt von dem ab, was Du vorhast. Wenn Dein Programm konstant alle zehn Sekunden einen neuen Wert ins array schreibt, ist das relativ egal, ob Du ein oder zehn Elemente zufügst. Dann ist ein Element einzufügen weniger Aufwand. Wenn die neuen Werte in Blöcken kommen, solltest Du auch das array blockweise vergrößern.

Wenn es um Performance bei schnellen Vorgängen geht, arbeitet man besser gleich mit festen arrays oder Du gibst gleich mit setlength eine feste Größe an - wenn Du weißt, dass ungefähr n Werte kommen reservierst den Speicher damit gleich. In der zweiten Variante kannst Du nach ein paar Monaten immer noch dranhängen.

Grüße, Messie

Luckie 10. Jun 2009 15:50

Re: dynamische Arrays vergrößern
 
Allerdings die Abbruchbedingung ist auch etwas mehr als abenteuerlich: "Lauf bis der Speicher voll ist." Und was passiert danach?

messie 10. Jun 2009 16:00

Re: dynamische Arrays vergrößern
 
Zitat:

Zitat von Luckie
Allerdings die Abbruchbedingung ist auch etwas mehr als abenteuerlich: "Lauf bis der Speicher voll ist." Und was passiert danach?

Da stand doch was von Abbruch im ersten Post.

Die Frage ist auch, was will man mit einer solchen Datenmenge im Speicher. Dafür gibt es Festplatten.

Aber solange die Aufgabe nicht klar beschrieben ist, können wir auch lange über eine gute Strategie der Datenverwaltung diskutieren. :mrgreen:

SimStar001 10. Jun 2009 20:32

Re: dynamische Arrays vergrößern
 
Zitat:

Zitat von alzaimar
Zitat:

Zitat von KahPee
Ist das vergrößern, der Länge um 10 schneller als das Vergrößern der Länge 10mal um 1?

Zitat:

Zitat von Luckie
Desweiteren hätte man sich diese Frage auch schnell durch ausprobieren beantworten können.

:zwinker:


Ich denke nicht, dass er dies hätte mit ausprobieren so eindeutig feststellen können! Oder :| :?:

himitsu 10. Jun 2009 20:44

Re: dynamische Arrays vergrößern
 
Delphi-Quellcode:
var
  a: Array of Integer;
  aLen, i, i2, i3: Integer;
  C, C2: LongWord;

begin
  C := GetTickCount;
  for i2 := 1 to 10000000 do begin
    i := Length(a);

    SetLength(a, i + 1);

    a[i] := 123456;
  End;
  C := GetTickCount - C;

  a := nil;
  aLen := 0;

  C2 := GetTickCount;
  for i2 := 1 to 10000000 do begin
    i := aLen;

    Inc(aLen);
    i3 := (aLen + $FF) and not $FF;
    if i3 <> Length(a) then SetLength(a, i3);

    a[i] := 123456;
  end;
  C2 := GetTickCount - C2;

  Application.MessageBox(PChar(Format('C = %d ms'#13#10'C2 = %d ms', [C, C2])), 'Test');
end;
Zitat:

---------------------------
Test
---------------------------
C = 1094 ms

C2 = 78 ms
---------------------------
OK
---------------------------

SimStar001 10. Jun 2009 20:56

Re: dynamische Arrays vergrößern
 
k überzeugt, aber wieso klappt das ganze bei der ersten methode nicht mit inc(i)? das wäre ja auch noch etwas schneller?

himitsu 10. Jun 2009 21:06

Re: dynamische Arrays vergrößern
 
das Inc fällt hier fast garnicht auf ... könnte auch aLen:=aLen+1; nehmen und es ändert sich nix.


bei obrigen Code (lezter Post), wird einfach nur das Array immer um 1 vergrößert,

ebenso wie hier ... hier wird die Länge auf i gesetzt und i ist 1 größer als die Länge:
Delphi-Quellcode:
var
  a: Array of Integer;
  aLen, i, i2, i3: Integer;
  C, C2: LongWord;

begin
  C := GetTickCount;
  for i2 := 1 to 10000000 do begin
    i := Length(a) + 1;

    SetLength(a, i);

    a[i - 1] := 123456;
  End;
  C := GetTickCount - C;

  a := nil;
  aLen := 0;

  C2 := GetTickCount;
  for i2 := 1 to 10000000 do begin
    i := aLen + 1;

    aLen := i;
    i3 := (aLen + $FF) and not $FF;
    if i3 <> Length(a) then SetLength(a, i3);

    a[i - 1] := 123456;
  end;
  C2 := GetTickCount - C2;

  Application.MessageBox(PChar(Format('C = %d ms'#13#10'C2 = %d ms', [C, C2])), 'Test');
end;
hier wird die länge aus der Zählervariable genommen
Delphi-Quellcode:
var
  a: Array of Integer;
  aLen, i, i2, i3: Integer;
  C, C2: LongWord;

begin
  C := GetTickCount;
  for i2 := 1 to 10000000 do begin
    i := i2;

    SetLength(a, i);

    a[i - 1] := 123456;
  End;
  C := GetTickCount - C;

  a := nil;
  aLen := 0;

  C2 := GetTickCount;
  for i2 := 1 to 10000000 do begin
    i := i2;

    aLen := i;
    i3 := (aLen + $FF) and not $FF;
    if i3 <> Length(a) then SetLength(a, i3);

    a[i - 1] := 123456;
  end;
  C2 := GetTickCount - C2;

  Application.MessageBox(PChar(Format('C = %d ms'#13#10'C2 = %d ms', [C, C2])), 'Test');
end;
wie gesagt, die zuweisung zu den Zählervariablen hat kaum Einfluß: ... hier verbraucht im Vergleich das Kopieren des Arrays sooooo viel Zeit.

Was aber auffäll ist, daß die Schrittweise verwaltung etwas mehr aufwand benötigt.
- 3 Zeilen, statt nur Einer
- es ist unübersichtlicher bzw. fehleranfälliger
- und man muß aLen verwenden, um die Anzahl der tatsächlichen Daten im Array zu bekommen und nich Length(a)

Luckie 10. Jun 2009 23:13

Re: dynamische Arrays vergrößern
 
Zitat:

Zitat von SimStar001
Ich denke nicht, dass er dies hätte mit ausprobieren so eindeutig feststellen können! Oder :| :?:

Das mit der Geschwindigkeit eventiull nicht so schnell, aber es ging ja ursprünglich darum ob der Inhalt erhalten bleibt, wenn man das dynamische Array vergrößert.

SimStar001 11. Jun 2009 19:06

Re: dynamische Arrays vergrößern
 
Ok stimmt, das hatte ich schon wieder vergessen...


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:08 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz