AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials Delphi Arrayoperationen beschleunigen
Tutorial durchsuchen
Ansicht
Themen-Optionen

Arrayoperationen beschleunigen

Ein Tutorial von himitsu · begonnen am 23. Nov 2006 · letzter Beitrag vom 28. Nov 2006
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von himitsu
himitsu
Registriert seit: 11. Okt 2003
Es ist ja wohl bekannt, daß bei vielen Änderungen der Arraygröße eine Menge Zeit draufgeht.

Dagegen gibt es eigentlich nur ein Mittel > die Anzahl der Änderungen muß verringert werden, so daß nicht gleich bei jeder kleinen Änderung der gesamte Arrayinhalt hin- und herkopiert wird.



Als Erstes könnte man es mal mit einem anderem Memory-Manager versuchen (z.B. Hier im Forum suchenFastMM),
allerdings ist es da nicht möglich das Verhalten an eigene Bedürfnisse anzupassen.


Also wäre es wohl nicht schlecht, wenn selber das Verhalten geändert wird.

1.) Verwendete und tatsächliche Größe unabhängig verwalten:
Wozu noch eine extra Variable für den verwendeten Bereich nötig wäre.
Code:
[b][color=blue]// Definition[/color][/b]
[b]Var[/b] MyArray: [b]Array of[/b] XXX;
  MyArray_Length: Integer;

[b][color=blue]// SetLength(MyArray, NewLength);[/color][/b]
MyArray_Length := NewLength;
SetLength(MyArray, [color=green](NewLength + $1FFF) [b]and not[/b] $1FFF[/color]);

[b][color=blue]// Length(MyArray)[/color][/b]
MyArray_Length

[b][color=blue]// High(MyArray)[/color][/b]
MyArray_Length - 1

[b][color=blue]// MyArray[Index][/color][/b]
MyArray[Index]


2.) Verwendete Größe mit Array speichern:
z.B. am Ende/nach den Array-Daten
Keine weitere Variable nötig, somit wären die Funktionen auf mehrere Arrays anwendbar.
Code:
[b][color=blue]// Definition[/color][/b]
[b]Type[/b] TMyArray = [b]Array of[/b] XXX;

[b]Var[/b] MyArray: TMyArray;

[b]Function[/b] Length_(Const A: TMyArray): Integer;
  [b]Begin[/b]
    [b]If[/b] A = nil [b]Then[/b] Result := 0
    [b]Else[/b] Result := PInteger(@A[High(A)])^;
  [b]End[/b];

[b]Function[/b] High_(Const A: TMyArray): Integer;
  [b]Begin[/b]
    Result := Length_(A) - 1;
  [b]End[/b];

[b]Procedure[/b] SetLength_([b]Var[/b] A: TMyArray; i: Integer);
  [b]Begin[/b]
    [b]If[/b] A <> nil [b]Then[/b] PInteger(@A[High(A)])^ := 0;
    [b]If[/b] i > 0 [b]Then[/b] [b]Begin[/b]
      SetLength(A, ([color=green](i + $1FFF) [b]and not[/b] $1FFF[/color]) + 1);
      PInteger(@A[High(A)])^ := i;
    [b]End Else[/b] A := nil;
  [b]End[/b];

[b][color=blue]// SetLength(MyArray, NewLength);[/color][/b]
SetLength_(MyArray, NewLength);

[b][color=blue]// Length(MyArray)[/color][/b]
Length_(MyArray)

[b][color=blue]// High(MyArray)[/color][/b]
High_(MyArray)

[b][color=blue]// MyArray[Index][/color][/b]
MyArray[Index]
Dieses Beispiel ist nur für SizeOf(XXX) >= 4,
wenn SizeOf(XXX) kleiner als SizeOf(Integer) ist, dann muß natürlich mehr als nur ein Feld für die zu speichernde Größenangabe verwendet werden.
Code:
[b]Function[/b] Length_(Const A: TMyArray): Integer;
  [b]Begin[/b]
    [b]If[/b] A = nil [b]Then[/b] Result := 0
    [b]Else[/b] Result := PInteger(@A[[color=red]Length(A) - 2{4}[/color]])^;
  [b]End[/b];

[b]Procedure[/b] SetLength_([b]Var[/b] A: TMyArray; i: Integer);
  [b]Begin[/b]
    [b]If[/b] A <> nil [b]Then[/b] PInteger(@A[[color=red]Length(A) - 2{4}[/color]])^ := 0;
    [b]If[/b] i > 0 [b]Then[/b] [b]Begin[/b]
      SetLength(A, ([color=green](i + $1FFF) [b]and not[/b] $1FFF)[/color] + [color=red]2{4}[/color]);
      PInteger(@A[[color=red]Length(A) - 2{4}[/color]])^ := i;
    [b]End Else[/b] A := nil;
  [b]End[/b];

[b][color=blue]// 2 für SizeOf(XXX)=2, oder SizeOf(XXX)=3
// 4 für SizeOf(XXX)=1[/color][/b]


3.) Größenangabe direkt im Array ändern:
Vorteil zum vorherigen (2) Vorgehen wäre, daß hier nur SetLength geändert werden muß.
Code:
[b][color=blue]// Definition[/color][/b]
[b]Type[/b] TMyArray = [b]Array of[/b] XXX;

[b]Var[/b] MyArray: TMyArray;

[b]Procedure[/b] SetLength_([b]Var[/b] A: TMyArray; i: Integer);
  [b]Begin[/b]
    [b]If[/b] A <> nil [b]Then[/b] PInteger(Integer(A) - SizeOf(Integer))^ :=
      [color=green](PInteger(Integer(A) - SizeOf(Integer))^ + $1FFF) [b]and not[/b] $1FFF[/color];
    SetLength(A, [color=green](i + $1FFF) [b]and not[/b] $1FFF[/color]);
    [b]If[/b] A <> nil [b]Then[/b] PInteger(Integer(A) - SizeOf(Integer))^ := i;
  [b]End[/b];

[b][color=blue]// SetLength(MyArray, NewLength);[/color][/b]
SetLength_(MyArray, NewLength);

[b][color=blue]// Length(MyArray)[/color][/b]
Length(MyArray)

[b][color=blue]// High(MyArray)[/color][/b]
High(MyArray)

[b][color=blue]// MyArray[Index][/color][/b]
MyArray[Index]


4.) Wer nicht direct im Array "rumpfuschen" möchte, könnte es auch mit einer Klasse versuchen.
Allerdings wird hierfür dann zusätzlich noch der Constructor und Destructor benötigt.
Code:
[b]Type[/b] TMyArrayClass = [b]Class[/b]
    Private
      A: [b]Array of[/b] XXX;
      ALen: Integer;
      [b]Function[/b] GetField(i: Integer): XXX;
      [b]Procedure[/b] SetField(i: Integer; Value: XXX);
    Public
      [b]Procedure[/b] SetLen(i: Integer);
      [b]Function[/b] Len: Integer;
      [b]Property[/b] LenX: Integer [b]Read[/b] Len [b]Write[/b] SetLen;
      [b]Property[/b] Field[i: Integer]: XXX [b]Read[/b] GetField [b]Write[/b] SetField; [b]Default[/b];
  [b]End[/b];

[b]Function[/b] TMyArrayClass.GetField(i: Integer): XXX;
  [b]Begin[/b]
    Result := A[i];
  [b]End[/b];

[b]Procedure[/b] TMyArrayClass.SetField(i: Integer; Value: XXX);
  [b]Begin[/b]
    A[i] := Value;
  [b]End[/b];

[b]Procedure[/b] TMyArrayClass.SetLen(i: Integer);
  [b]Begin[/b]
    SetLength(A, [color=green](i + $1FFF) [b]and not[/b] $1FFF[/color]);
    ALen := i;
  [b]End[/b];

[b]Function[/b] TMyArrayClass.Len: Integer;
  [b]Begin[/b]
    Result := ALen;
  [b]End[/b];

Var MyArray: TMyArrayClass;

[b][color=blue]// Initialisieren[/color][/b]
MyArray := TMyArrayClass.Create;

[b][color=blue]// SetLength(MyArray, NewLength);[/color][/b]
MyArray.SetLen(NewLength);
[b][color=blue]{oder}[/color][/b] MyArray.LenX := NewLength;

[b][color=blue]// Length(MyArray)[/color][/b]
MyArray.Len
[b][color=blue]{oder}[/color][/b] MyArray.LenX

[b][color=blue]// High(MyArray)[/color][/b]
MyArray.High

[b][color=blue]// MyArray[Index][/color][/b]
MyArray[Index]
[b][color=blue]{oder}[/color][/b] MyArray.Field[Index]

[b][color=blue]// Finalisieren[/color][/b]
MyArray.Free;






Fazit:
Aus OOP-Sicht wäre 4. zu bevorzugen,
auch wenn da vieles zu beachten und zu verändern ist.

Bei 1. ist zwar guz zu sehn was gemacht wird, allerdings mu da jedes SetLength, Length und High geändert werden.

2. ist im Grunde nicht zu empfehlen, da dort das Array besser mit SelLength_(MyArray, 0) freigegeben werden sollte, vorallem wenn im Typ dynamische Stukturen enthalten sind, welche von FinalizeArray behandelt werden (z.B. Strings), da es sonst Probleme mit dem Typ-Fremden Integer (der Längenangabe am Ende) geben könnte.
Schließlich wird aus gutem Grund die Größenangabe aus dem Array gelöscht, bevor die Größe geändert wird. If A <> nil Then PInteger(@A[High(A)])^ := 0;
Ich selber verwende gerne 3., da hierbei nur SetLength ersetzt werden muß und alles andere unverändert bleibt.
Außerdem kann dieses Array überall so verwendet werden, als wäre es ein ganz normalles Array.
Manchmal auch 1., da es ja im Grunde genau das Selbe wie 2. ist, nur halt etwas schneller.




Schrittweite:
In den Beispielen wird die Arraygröße jeweils in Schritten von 1024 geändert.

Es sind natürlich auch andere Werte möglich,
aber im allgemeinen sind 2er-Potenzen idealer, da dort binär (mit AND) gerechnet werden kann,
wärend sonst mathematische Rechnungen (mit MOD und *) nötig sind.

Also einmal ein "schnelles" AND (das NOT wird mit einkopiliert),
oder zweimal "langsame" DIV/MUL.

Code:
[b][color=blue]// binär (nur bei 2er-Potenzen)[/color][/b]
[color=green](i + (AllocSize - 1)) [b]and not[/b] (AllocSize - 1)[/color]
[b][color=blue]{=}[/color][/b] [color=green](i + $*****) [b]and not[/b] $*****[/color]

[b][color=blue]// matematisch[/color][/b]
[color=darkgreen]((i + (AllocSize - 1)) [b]div[/b] AllocSize) * AllocSize[/color]
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
 
alzaimar

 
Delphi 2007 Enterprise
 
#11
  Alt 24. Nov 2006, 15:07
Also das mit den 172% oder 176% oder was auch immer habe ich auch schon gehört, deckt sich aber nicht mit meinen Versuchen. Ich habe meine Arrays einfach immer von der Größe her verdoppelt. Das ist unterm Strich schneller als die 176% und auch nachvollziehbar: Es wird ja seltener vergrößert.

Kann mir jemand mathematisch beweisen, das die 172/176% optimal sind? Also ich meine, das es umso optimaler wird, je größer der Vergrößerungsfaktor ist. Nur praktikabel ist es nicht.
  Mit Zitat antworten Zitat
Der_Unwissende
 
#12
  Alt 24. Nov 2006, 15:52
Zitat von alzaimar:
Kann mir jemand mathematisch beweisen, das die 172/176% optimal sind? Also ich meine, das es umso optimaler wird, je größer der Vergrößerungsfaktor ist. Nur praktikabel ist es nicht.
Nicht dass das noch ansatzweise zum eigentlichen Topic gehört, aber optimal in Bezug auf was? Laufzeit oder Speicherausnuztung? Und für Letzteres wäre sicherlich mehr reservieren suboptimal. Aber ich glaube, dass keiner behauptet hatte, dass die 172/176% optimal sind, oder?

Aber mal interesse halber, mit welcher Größe startest du denn? Da hast du doch sicherlich auch einen Erfahrungswert, denke nicht dass du erst 1 Element hast und dann immer verdoppelst.

Gruß Der Unwissende
  Mit Zitat antworten Zitat
alzaimar

 
Delphi 2007 Enterprise
 
#13
  Alt 24. Nov 2006, 16:09
Zitat von Der_Unwissende:
Nicht dass das noch ansatzweise zum eigentlichen Topic gehört, aber optimal in Bezug auf was? Laufzeit oder Speicherausnuztung? Und für Letzteres wäre sicherlich mehr reservieren suboptimal. Aber ich glaube, dass keiner behauptet hatte, dass die 172/176% optimal sind, oder?

Aber mal interesse halber, mit welcher Größe startest du denn? Da hast du doch sicherlich auch einen Erfahrungswert, denke nicht dass du erst 1 Element hast und dann immer verdoppelst.
Doch, ich finde, das gehört zum Topic "Arrayoperationen beschleunigen". Und da es um "Beschleunigen" geht, ist logischerweise das "optimal" auf die Geschwindigkeit bezogen, insofern ist deine Frage überflüssig. Und es wird behauptet, die 172/176% seien irgendwie 'besser' als andere Faktoren, nicht unbedingt in diesem Thread, aber allgemein. Ich halte diese "magische Zahl" übrigens für einen Hoax, aber das nur am Rande.

Ich habe eine TStringDictionary , die arbeitet mit einer Hashmap, und die ist als ein Array implementiert. Wenn die Hashmap voll ist, muss ich das Array vergrößern. Ich habe mit 1.72 2/3, Fibbionacci etc. experimentiert und bin schlussendlich bei der 2 geblieben (als Vergrößerungsfaktor). 4 ist noch besser, aber so marginal, das mir da die 2 lieber ist.

Meine Anfangsgröße ist 997 (Primzahl, ist so bei Hashmaps), wobei es wirklich egal ist ob man mit 1 oder 997 anfängt. Jedenfalls bei meinen Versuchen, die 1-10 Millionen Strings in die Liste eingefügt haben.

Bis 2^31 Einträge in der Liste sind, wird diese bei einer Anfangsgröße von 997 Elementen 20x vergrößert. Ob ich beim Einfügen von 2^31 Elementen nun 30 (Anfangsgröße = 1) oder 20x vergrößere ist völlig egal: Das Laufzeitverhalten bleibt gleich, denn die 10 anfänglichen Vergrößerungen (Anfangsgröße=1, bis auf 1000 Elemente) geht einfach zu schnell und gehen in der Messung über die 1.000.000 Elemente unter.

Damit die StringDictionary auch für kleinere Mengen praktikabel ist, habe ich die Anfangsgröße doch auf 997 gesetzt. Damit kommen normale Anwendungen gänzlich ohne dynamische Vergrößerung aus.

Wenn ich dagegen mit kleineren Faktoren spiele, wird das Teil doch etwas langsamer. Also habe ich mich für 200% entschieden, was im Code auch irgendwie cooler aussieht, also (*1.72), obwohl das Geschmackssache ist.

Übrigens ist es entgegen meiner anfänglichen Meinung nicht so, das es umso schneller ist, je höher der Vergrößerungsfaktor ist. Ich hab mal die Kurve der zu Gesamtanzahl der zu verschiebenden Elemente ggü dem Vergrößerungsfaktor aufgezeichnet und das lokale Minimum liegt irgendwo bei 4-5 (sofern meine Formel stimmt).
  Mit Zitat antworten Zitat
Der_Unwissende
 
#14
  Alt 24. Nov 2006, 18:30
Zitat von alzaimar:
Doch, ich finde, das gehört zum Topic "Arrayoperationen beschleunigen". Und da es um "Beschleunigen" geht, ist logischerweise das "optimal" auf die Geschwindigkeit bezogen, insofern ist deine Frage überflüssig.
Entschuldige, war gerade geistig noch in einem anderen Thread, nehme alles zurück! Erst lesen, dann schreiben, da war doch was. Tut mir echt leid!

An die Messungen und die Hashmaps (gab doch einmal eine String und einmal eine Integer basierte?) kann ich mich (wieder ohne nochmal zu lesen) noch erinnern, die waren/sind echt gut/flink!

Ja, sorry nochmal, nichts für ungut! Hier in dem Thread gebe ich dir natürlich völlig recht!

Gruß Der Unwissende
  Mit Zitat antworten Zitat
alzaimar

 
Delphi 2007 Enterprise
 
#15
  Alt 24. Nov 2006, 18:37
Ich hab mich schon gewundert, aber lass man, liegt am Wetter: Ich war dafür gestern dumm wie Brot.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#16
  Alt 24. Nov 2006, 18:37
Zitat von Der_Unwissende:
An die Messungen und die Hashmaps (gab doch einmal eine String und einmal eine Integer basierte?) kann ich mich (wieder ohne nochmal zu lesen) noch erinnern, die waren/sind echt gut/flink!
Hier geht es mehr um das Array selber, wie man die Datenverarbeitung innerhalb des Arrays beschleunigt ist 'ne andere Sache.



[add]
klar sind die kurzen Inlineversionen schnell und schön ... verwende die kleinen Zwei-/Dreizeiler auch recht oft ... hab's da oben zwar schön in Funktionen verpackt (weil etwas übersichtlicher), aber nimand verbietet es einem, wenn man es direkt im Code verwendet (so wie z.B. bei 1.)
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH
 
#17
  Alt 24. Nov 2006, 20:08
Zitat:
1.) Neuere Delphi-Compiler sollten den inlinen
2.) ja. geht bestimmt auch per boolescher Verknüpfungen... aber das kann ich nicht^^
3.) Naja... man kann dafür auch eine zusätzliche variable deklarieren^^
4.) Wärs die lieber als typisierte private Konstante? Wink Kann man natürlich jederzeit innerhalb der am nchsten gelegenen Klasse deklarieren Wink
Hm, meine Antwort, einfach mal als Kontrapunkt betrachten

1.) davon weiß ich nichts und ich kenne keinen Compiler der einfach mal so aus überschwenglicher Eigenkreativität eine Funktion als Inline compiliert bei der der Programierer es nicht explizit vorgegeben hat. Viel eher ist meine Erfahrung, egal ob PASCAL/C Compiler, das Inline Funktionen bei weitem eben nicht das gleiche sind wie zb. Makros oder direkter Code. Viele Compiler machen da einen Unterschied wenn es um die Optimierung geht.

2.) Nein geht per Boolscher Verknüpfung eben nicht. Du multiplizierst mit einer Fließkommazahl und das kannst du nicht in Boolscher Algebra rechnen. Integer mod 256 = 0 geht degeben sehr wohl, da der Compiler das in Integer and $FF = 0 umsetzten kann.

3.) Und noch eine zusätzliche globale Variable, obwohl doch nur 3 zusätzliche Zeile im Sourcecode das Problem lokal lösen können.

4.) Hm, wieder ein Kniff obwohl die Lösung doch simpel ist

Ich meine das man die Logik beim Programmieren nicht so ansetzten sollte das man für alles eine fertige Klasse oder Bibliothek benötigt, schon garnicht für so wirklich simple Sachen. Manchesmal denke ich das viele Leute ein Problem versuchen viel komplizierter zu machen, ganz im Gegensatz zur Grundaufgabe eines Programmieres -> lösen von Problemen auf die einfachste Art.

Das soll jetzt keine Kritik an deiner Person oder deinem Vorschlag sein. Einfach nur so'n par Argumente die mir spontan in der Birne rumsausen

@alzaimar:

Ähnliche Erfahrungen habe ich auch gemacht. Bisher habe ich noch nie eine Faustformel gefunden die auf alle Algorithmen und Problemstellungen und Datenaufkommen und underlaying Bibliotheksimplementierungen anwendbar ist. Die bisher beste durchschnittliche Vorgehensweise war die binäre Quadratische Annäherung, also die Verdopplung/Halbierung in unserem Fall. Am besten 2'er Potenzen. Das deckt sich in irgendeinerweise auch mit vielen anderen Verfahren wie "Binary Splitting-Divide & Conquer", "Binäre Suche", "QuickSort" etc.pp. Allerdings bin ich bei der Speicherallokation sehr sehr konservativ und alloziere lieber linear um einen Betrag +X. Am besten ist es aber wenn man schon von vornherein das Datenaufkommen kennt und dann gezielt reagieren kann. Und exakt das ist möglich wenn man im Gesamtkonzept seiner Programmierung darauf Einfluß nehmen kann. Die beste Optimierung findet also an diesem Punkt statt.

Man muß fairerweise aber auch sagen das wir hier über "Details" diskutieren, denn sehr oft sind es nicht solche Allozierungen wie diese hier im Forum die den Flaschenhals darstellen.

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#18
  Alt 25. Nov 2006, 13:29
Was das zuviele Length-Aufrufen angeht:

Bis auf die ersten beiden Varianten gibt's da wohl nicht mehr sooooviel Unterschied,
Delphi-Quellcode:
// if length(Arr) = 0 then
if Arr = nil then

// If Length(Arr) <> 0 Then
// If Length(Arr) > 0 Then
If Arr <> nil Then

// If Length(Arr) > 123 Then
If (Arr <> nil) and (PInteger(Integer(Arr) - 4)^ > 123) Then

// If Length(Arr) < 123 Then
If (Arr = nil) or (PInteger(Integer(Arr) - 4)^ < 123) Then

...
wenn man sich dagegen die Funktion ansieht ... abgesehen von dem zusetzlichen 2 Sprüngen (zur Funktion und zurück).

den nach Pascal übersetzt sieht die ja in etwa so aus:
Code:
Function Length(Arr): Integer;
  Begin
    If Arr = nil Then Result := 0
    Else Result := PInteger(Integer(Arr) - SizeOf(Integer))^;
  End;


PS an Borland: wie wäre es ohne die Funktion und direkt Inline (wie oben)?



Aber wer auf Kurz steht ... hier nochmal die Zwei-/Dreizeiler as InlineCode:
Code:
// entspricht 2.
[b]If[/b] [color=red]Arr[/color] <> nil [b]Then[/b] PInteger(Integer([color=red]Arr[/color]) - 4)^ := (PInteger(Integer([color=red]Arr[/color]) - 4)^ + [color=green]255[/color]) [b]and[/b] -[color=green]255[/color];
SetLength([color=red]Arr[/color], ([color=blue]NewSize[/color] + [color=green]255[/color]) [b]and[/b] -[color=green]255[/color]);
[b]If [color=red]Arr[/color] <> nil [b]Then[/b] PInteger(Integer([color=red]Arr[/color]) - 4)^ := [color=blue]NewSize[/color];


Code:
// ist zwar schneller/kürzer, aber es wird immer die Längen-Variable benötigt
SetLength([color=red]Arr[/color], ([color=blue]NewSize[/color] + [color=green]255[/color]) and -[color=green]255[/color]);
[color=red]ArrLen[/color] := [color=blue]NewSize[/color];

// und will man mal das Array ohne ArrLen weitergeben,
// sollte/muß die tatsächliche Länge nochmals angepaßt werden:
SetLength([color=red]Arr[/color], [color=red]ArrLen[/color]);


Dann sei nochmals darauf hingewiesen, daß "einige" eurer Codes das Array nur vergrößern
und speziell Hagen's Methoden mit MOD setzen voraus, daß immer ein bestimmter Punkt getroffen wird, bevor vergrößert/geändert wird.

Gut, bei mir ist es dagegen dann zwar nicht mehr ganz optimal, aber dafür kann/darf man dort auch mal in unterschiedlichen Schritten ändern und natürlich das Array auch wieder verkleinern.



Und ja, Methode 7 (siehe negaH) ist natürlich das Optimum, da dort nur einmal und genau auf das was nötig ist geändert wird.
  Mit Zitat antworten Zitat
alzaimar

 
Delphi 2007 Enterprise
 
#19
  Alt 27. Nov 2006, 07:21
Hmitsu: Ich verstehe Dein bestreben, inline-Code zu erzeugen, aber wäre es nicht wirklich sinnvoller, die Array-Größe zu verdoppeln (oder zu vereinskommasiebenzweifachen )? Dann ist es doch völlig egal, wie die SetLength-Routine arbeitet, nur bei der 'Length'-Funktion könnte man sich einen Funktionsaufruf sparen. Hier allerdings wäre es sicherlich noch einen Tick schneller, die aktuelle Größe des Arrays in einem Feld zu speichern... Wäre das nicht *noch* schneller?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#20
  Alt 28. Nov 2006, 12:33
Ich hab ja nichts dagegen, wenn man die aktuelle Größe in einer Extravariable speichert (siehe 1.),
nud kann das auch mal schnell unübersichtlich/unpraktisch werden.
z.B. bei vielen Arrays, oder wenn man das Array dann an andere (fremde) Funktionen übergeben möchte, denn da muß man dann entweder die zusätzliche Variable mitgeben, wenn das überhaupt geht).


Ansonsten mag verdoppeln, oder bei raschem anwachsen ein vermehrfachen recht schick,
aber bei "sehr" großen Arrays wohl auch nicht mehr gut (z.B. Speicherauslagerung durch Windows und massig ungenutzt reservierten Speicher).
Da ist dann wohl ein gut gewählter, fester Wert auch nicht zu verachten.



PS: auch wenn ich selber oftmals InlineCode verwende, waren die Inlines von mir nur wegen der "Funktions-Hasser" (nicht böse und ganz ernst gemeint).


Naja, daß die Standardfunktionen nicht so ganz optimal sind ist wohl klar und inzwischen sind hier wohl auch schon 'ne ganze Menge Möglichkeiten zusammengekommen, wie man da was verbessern könnte.
Und am Ende kommt es eh auf jeden Programmierer und das Programm drauf an, was wohl die bessere Lösung ist.


Und bei wenigen/seltenen Größenänderungen lohnt sich der "Aufwand" eh kaum.



Zitat von negaH:
Man muß fairerweise aber auch sagen das wir hier über "Details" diskutieren, denn sehr oft sind es nicht solche Allozierungen wie diese hier im Forum die den Flaschenhals darstellen.
Na ja, ein Flaschenhals ist es dennoch.

Alleine mit sowas konnte ich z.B. in h-Sync die Verarbeitung von vielleicht 3 bis 4 Dateien die Sekunde auf knapp 1000 raufschrauben ... zum Ende hin, bei 'ner 7-stelligen Anzahl an Dateien.

Klar ist das nicht die einzige Engstelle, aber jede "kleine" vorteil verbessert das Gesamtergebnis.
Und vorallem dann, wenn es sich um soeine winzige Veränderung handelt, welche dennoch große Wirkungen zeigen kann.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:11 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz