25.08.2010, 10:31
Beitrag #1
|
Karotte
Unregistered
|
Array befüllen verlangsamt sich zusehens
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
|
|
|
25.08.2010, 10:37
Beitrag #2
|
Matze
LVF-Team
Beiträge: 1.027
Registriert seit: Apr 2010
20xx
2010
DE_EN
7xxxx
Deutschland
|
Array befüllen verlangsamt sich zusehens
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
|
|
|
25.08.2010, 11:24
Beitrag #4
|
Karotte
Unregistered
|
Array befüllen verlangsamt sich zusehens
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?
|
|
|
25.08.2010, 11:36
(Dieser Beitrag wurde zuletzt bearbeitet: 25.08.2010 11:37 von Matze.)
Beitrag #5
|
Matze
LVF-Team
Beiträge: 1.027
Registriert seit: Apr 2010
20xx
2010
DE_EN
7xxxx
Deutschland
|
Array befüllen verlangsamt sich zusehens
' 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.
|
|
|
25.08.2010, 12:29
Beitrag #6
|
Karotte
Unregistered
|
Array befüllen verlangsamt sich zusehens
Danke!
Es geht nun schon deutlich schneller
|
|
|
25.08.2010, 12:49
Beitrag #7
|
Lucki
Tech.Exp.2.Klasse
Beiträge: 7.699
Registriert seit: Mar 2006
LV 2016-18 prof.
1995
DE
01108
Deutschland
|
Array befüllen verlangsamt sich zusehens
' 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.
|
|
|
25.08.2010, 13:24
(Dieser Beitrag wurde zuletzt bearbeitet: 25.08.2010 13:25 von Matze.)
Beitrag #8
|
Matze
LVF-Team
Beiträge: 1.027
Registriert seit: Apr 2010
20xx
2010
DE_EN
7xxxx
Deutschland
|
Array befüllen verlangsamt sich zusehens
' 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.
|
|
|
25.08.2010, 16:15
(Dieser Beitrag wurde zuletzt bearbeitet: 25.08.2010 16:19 von Lucki.)
Beitrag #9
|
Lucki
Tech.Exp.2.Klasse
Beiträge: 7.699
Registriert seit: Mar 2006
LV 2016-18 prof.
1995
DE
01108
Deutschland
|
Array befüllen verlangsamt sich zusehens
' 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.
Vorinitialisierung auf 10^6 Elemente (Bei Array anhängen nicht erforderlich), Auffüllen mit 10^5 Elementen:
lv90
Array_erstellen_Test.vi (Größe: 12,25 KB / Downloads: 234)
|
|
|
25.08.2010, 16:27
|
Matze
LVF-Team
Beiträge: 1.027
Registriert seit: Apr 2010
20xx
2010
DE_EN
7xxxx
Deutschland
|
Array befüllen verlangsamt sich zusehens
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.
|
|
|
| |