LabVIEWForum.de - Array befüllen verlangsamt sich zusehens

LabVIEWForum.de

Normale Version: Array befüllen verlangsamt sich zusehens
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.

Karotte

Hallo,

ich parse eine Datei, die aus ca. 8500 Einträgen besteht 'sog. Devices'. Jeder Eintrag wiederrum hat mehrere Schlüsselworte.
Ich will diese Daten in einem Array aus Clustern abspeichern. Jedes Cluster besteht derzeit aus Strings, die Werte hinter den Einzelnen Schlüsselworten enthalten.

Derzeit gehe ich so vor, dass beim Auffinden eines neuen Eintrags in der Datei ein neues Cluster an mein (zu Anfang leeres) Array angehängt wird. Dieses Vorgehen bewirkt jedoch, dass mit wachsender Länge des Arrays das Eintragen der Daten immer langsamer wird.
Das dieser Vorgang Zeit benötigt, ist mir klar, aber ich hätte erwartet, dass das Erstellen eines neuen Elements im Array gleich lange dauert.

Also habe ich mir gedacht, dass der Rechner im Hintergrund ja jedesmal das Array resizen muss, also Speicher allokiert, etc. was mit wachsender Größe des Arrays immer länger Dauert.

Aus diesem Grund wollte ich nun so vorgehen, dass ich erst ermittle wieviele Einträge meine Datei enthält, anschließend einmal die Größe des Arrays anpasse und zum Schluss erst her gehe und die Elemente des Arrays mit Daten fülle.

Was haltet ihr davon? Ist dies sinnvoll? Oder sollte ich einen anderen Weg gehen?

Als nächstes stellt sich für mich die Frage, wie ich die Größe des Arrays vorher festlegen kann? Es gibt zwar das 'Initialize Array', das benötigt jedoch als Eingabeparameter ein Element und kein existierendes Array. Ich will aber mein existierendes Array initialisieren.

mfg

Christian
Hallo

' schrieb:Also habe ich mir gedacht, dass der Rechner im Hintergrund ja jedesmal das Array resizen muss, also Speicher allokiert, etc. was mit wachsender Größe des Arrays immer länger Dauert.
Vollkommen richtig.

' schrieb:Aus diesem Grund wollte ich nun so vorgehen, dass ich erst ermittle wieviele Einträge meine Datei enthält, anschließend einmal die Größe des Arrays anpasse und zum Schluss erst her gehe und die Elemente des Arrays mit Daten fülle.

Was haltet ihr davon? Ist dies sinnvoll? Oder sollte ich einen anderen Weg gehen?
Das ist genau der richtige Weg.

' schrieb:Es gibt zwar das 'Initialize Array', das benötigt jedoch als Eingabeparameter ein Element und kein existierendes Array. Ich will aber mein existierendes Array initialisieren.
Nein, du gehst her und erstellst dir über "Array initialisieren" ein neues Array. Dieses enthält die Anzahl an Elementen und Standardwerte.
In deiner Schleife ersetzt du dann diese Werte mit denen aus deiner Datei.

Grüße
Um dein Array zu initialisieren, schließt du einfach ein Element an Initialize Array an und gibst die Dimension vor.

Nur mal so daher geredet:

Du kannst die Datei einmal zeilenweise lesen... dann weißt du die Dimension für dein Array.

Du kannst einfach ein Array mit 1000 initialisieren und wenn dein Arrayindex sich der 999 nähert, initialisierst du ein neues Array mit "alte Arraydimension + 1000" und so weiter... da einfach das alte Array in das neue kopieren.

Du kannst auch immer erst 50 Einträge lesen und in ein klienes Array packen, wenn das voll ist hängst du es an dein großes Array an...

Das große Array für jeden Eintrag neu zu erzeugen ist ja blöd und das hast du ja auch schon geschrieben...



Gruß SeBa

Karotte

Wenn ich kein Element des Typs, der im Array zusammen gefassst ist, zur Verfügung habe, muss ich mir also ein Dummy-Element erzeugen, nur damit ich ein passendes Array initialisieren kann?
In meinem Fall ist das ja ein Cluster.
Also muss ich noch ein Dummy-Cluster in das VI packen, auch wenn ich es direkt nicht verwenden werde?
' schrieb:Wenn ich kein Element des Typs, der im Array zusammen gefassst ist, zur Verfügung habe, muss ich mir also ein Dummy-Element erzeugen, nur damit ich ein passendes Array initialisieren kann?
In meinem Fall ist das ja ein Cluster.
Also muss ich noch ein Dummy-Cluster in das VI packen, auch wenn ich es direkt nicht verwenden werde?
"Array initialisieren" muss den Typ des Arrays natürlich kennen. Eine Cluster-Konstante o.ä. musst du somit verwenden, ja. Also irgendwo im VI, wo du den Cluster nutzt (evtl. eine Typendefinition): Rechtsklick -> Erstellen -> Konstante.
Und diese mit dem Array-Eingang verbinden.
Vielleicht kannst du auch den Cluster-Draht zu deinem Array verzweigen. Dann brauchst du keine separate Konstante.

Mit LV 2010 könnte man solche Konstanten auch als kleines Symbol darstellen. Sonst gebe ich zu, dass das Blockdiagramm sehr unübersichtlich werden kann.

Karotte

Danke!

Es geht nun schon deutlich schnellerSmile
' schrieb:Als nächstes stellt sich für mich die Frage, wie ich die Größe des Arrays vorher festlegen kann? Es gibt zwar das 'Initialize Array', das benötigt jedoch als Eingabeparameter ein Element und kein existierendes Array. Ich will aber mein existierendes Array initialisieren.
Das ist ganz einfach geworden, seitdem es in LV For-Schliefen mit der Möglichkiet des vorzeitigen Abbruchs gibt. Also: an N genügend große Konstante entsprechend der geplanten Vorinitialisierungs-Größe anschließen. Ergebnisse zum Ausgang mit Autoindexierung. Die Schleife vorher enstprechend der erreichten Bedingung abbrechen.
' schrieb:Das ist ganz einfach geworden, seitdem es in LV For-Schliefen mit der Möglichkiet des vorzeitigen Abbruchs gibt. Also: an N genügend große Konstante entsprechend der geplanten Vorinitialisierungs-Größe anschließen. Ergebnisse zum Ausgang mit Autoindexierung. Die Schleife vorher enstprechend der erreichten Bedingung abbrechen.
Soweit ich weiß sollte das Auto-Indexing der For-Schleife nur dann verwendet werden, wenn die For-Schleife nicht vorzeitig abgebrochen wird.
Das ist meines Wissens der Nachteil, der bei diesem Bedingungsanschluss der For-Schleife öfters erwähnt wird.

Eigentlich ist es auch klar, denn Auto-Indexing ist vermutlich nichts anderes als ein Vorbelegen des Arrays zu Beginn. Die Größe ist dabei durch N bzw. einen indizierten Eingang vorgegeben. Verlässt man die For-Schleife nun vorzeitig, weiß ich nicht, was genau passiert. Vielleicht wird nur Speicher verschenkt, vielleicht ist die Performance schlechter, vielleicht kann's auch mal schief gehen.
' schrieb:Soweit ich weiß sollte das Auto-Indexing der For-Schleife nur dann verwendet werden, wenn die For-Schleife nicht vorzeitig abgebrochen wird.
Das ist meines Wissens der Nachteil, der bei diesem Bedingungsanschluss der For-Schleife öfters erwähnt wird.
Wo sollte das jemals erwähnt worden sein? Wenn ja, dann vielleicht von Leuten, die sich einfach so was denken und dabei von dummen Programmiereren bei NI ausgehen?
Zitat:Eigentlich ist es auch klar, denn Auto-Indexing ist vermutlich nichts anderes als ein Vorbelegen des Arrays zu Beginn. Die Größe ist dabei durch N bzw. einen indizierten Eingang vorgegeben.
Klar ist eigentlich gar nichts. Obwohl alles richtig ist, was in dem Zitat nach dem Wort "klar" geschrieben steht.
Zitat:Verlässt man die For-Schleife nun vorzeitig, weiß ich nicht, was genau passiert. Vielleicht wird nur Speicher verschenkt, vielleicht ist die Performance schlechter, vielleicht kann's auch mal schief gehen.
Man weiß es aber dann, wenn man einfach mal davon ausgeht, wie man das selbst als zuständiger Programmierer optimal handhaben würde und wenn man weiterhin davon ausgeht, das die Leute bei NI mindesten genau so klug sind.
Die Antwort ist dann: Der mit Daten noch nicht aufgefüllte Teil des vorinitialisierte Array wird abgeschnitten.
Zusammengefasst heißt das: Es wird alles genau so gemacht, wie es als die bessere Alternative zum fortlaufenden Anhängen neuer Elemente bei großen Datenmengen empfohlen wird: Initialisieren eines Array maximaler Größe, Ersetzen von Elementen, Kürzen des Arrays auf die tatsächlich belegte Elementezahl.

Habe mal einen Performance-Test gemacht, man will ja vorher wissen ob man Recht hat bevor man sich weit aus dem Fenster lehnt.Mellow
Vorinitialisierung auf 10^6 Elemente (Bei Array anhängen nicht erforderlich), Auffüllen mit 10^5 Elementen:

[attachment=29002]
lv90 [attachment=29003]
Bei mir hat's bisher auch immer gut geklappt. Aber entweder hier oder in den NI-Foren wurde das von jemandem geschrieben.
Und das war sicher kein Anfänger, sonst würde ich mir sowas nicht merken.

Aber wenn es klappt ist es ja ok.
Referenz-URLs