Hallo Leute,
gerade verwende ich Labview um große Datenmengen zu speichern. Hierfür habe ich eine globale Variable definiert. Diese Variable besitzt ein Array, in das ich bei jeder Messwertaufnahme 4 Datenstrings in einer Zeile anhänge. Das funktioniert soweit gut.
Insgesamt möchte ich über 200000 dieser Zeilen in das Array einfügen.
Das Problem ist, das ab ungefähr 30000 Werten das Array irgendwie zu groß wird und der PC zu langsam wird beim Hinzufügen der Daten. Hierfür muss ich dann das Array in eine Datei speichern und es leeren. Dann funktioniert es wieder gut.
Im Bild sieht man ja, dass ich die globaleVariable immer erst auslese und dann wieder neu beschreibe, was wohl bei der Werteanzahl nicht sinnvoll ist. Wie hänge ich aber etwas an eine Variable an ohne diese zu lesen?
Freundliche Grüße
Bernhard
Hallo dunst,
1.) Globale Variablen sind eher ungeeignet, um große Datenmengen zu speichern: sie führen aufgrund der nötigen Datenkopien noch eher zu "Out of memory"-Problemen als andere Methoden.
2.) Deine Methode, ArraySize und InsertIntoArray zu kombinieren, ist ebenfalls ungünstig. Einfacher wäre hier ein simples BuildArray…
Tipps:
- Lese dich ins Thema "FGVs" ein.
- Lese die LabVIEW-Hilfe zum Thema "Handling großer Datenmengen".
- Überlege dir ein besseres Datenmanagment…
3.) Die Sequenzstruktur ist im gezeigten Kontext unnötig.
4.) Es gibt ein AutoCleanup-Tool…
Der Zaubertrick bei großen Datenmengen ist auf jeden Fall: Neue Daten mit "ersetzen" einfügen statt anzuhängen. Also: (i) Das Array auf maximale Datengröße vorinitialisieren, (ii) Die neuen Werte mit "ersetzen" in die vorinitialisierten Werte einfügen. (iii) zum Schluss das Array auf den tatsächlich mit Daten angefüllten Teil kürzen. (Der logistische Aufwand ist etwas größer, aber es lohnt sich)
Damit bist Du auf Anhieb mindestens 100 mal schneller. Ob Du globale Variable, FGV, oder etwas anderes nimmst, hat auch einen gewissen Einfluss auf die Schnelligkeit. Im Vergleich zu obiger Änderung ist das aber eher marginal bis vernachlässigbar. Das Schnellste wäre die Speicherung in einem Schieberegister. Globale Variablen werden gewöhnlich verwendet, um von mehreren VIs auf die Daten zugreifen zu können. Brauchst Du das hier überhaupt?
Hi,
danke für eure Antworten. Ja die globale Variable verwende ich in unterschiedlichen VIs. Insgesamt ist das Projekt sehr groß geworden.
Klar ist die Sequenzstruktur nötig, ich habe nur einen kleinen Teil ausgeschnitten wegen der globalen Variable.
Naja, ich weiß es gibt ein AutoCleanup-Tool. Ich programmiere aber lieber so wie ich denke, bzw. nach meinen Überlegungen. Wenn das danach durch den Häcksler gedrückt wird wenn es funktioniert ist mir egal. So unansehnlich finde ich die drei Blöcke nun auch nicht...
Ich habe nach FGVs gegoogelt. Kp was das ist
Datenmanagment? Pfff
Nein, Spaß bei Seite, ich bekomme dafür kein Geld und die Motivation ist bei Null mich tiefer in Labview einzuarbeiten. Aber deine Schritte sind wohl richtig.
Der Zaubertrick hört sich gut an! Werde ich testen. Lässt sich umsetzen und vielleicht funktionierts. Danke
(16.04.2014 21:05 )dieseldunst schrieb: [ -> ]Ich habe nach FGVs gegoogelt. Kp was das ist Datenmanagment? Pfff
Nein, Spaß bei Seite, ich bekomme dafür kein Geld und die Motivation ist bei Null mich tiefer in Labview einzuarbeiten. Aber deine Schritte sind wohl richtig.
hmm ... klingt nach den besten Voraussetzungen für eine gut funktionierende, performante und zuverlässige LabVIEW-Anwendung
in deinem Fall kann ich dir nur den Tip geben dich an den ehernen Grundsatz der Software-Entwicklung zu halten: "real programmers don't document!"
- dann ist der Erfolg - wie auch immer man den nun definieren will - garantiert
viele Grüße
cb
Naja was soll ich sagen, es funktioniert alles super. In meinem Fall die Hauptsache. (Bis auf das Ding mit den großen Datenmengen.)
Es gibt halt noch eine Stufe zwischen Profi und "Ich weiß wie man mit einem Schalter eine LED anschaltet"
Das Problem mit dem großen Array hättest du in vielen Programmiersprachen, das ist jetzt nicht LabVIEW spezifisch:
Aktuell hängst du bei jedem Durchlauf eine neue Zeile an das schon bestehende 2D Array an. Jetzt muss jedesmal der LabVIEW Memory-Manager neuen Speicher Platz suchen und allozieren, das dauert bei großen Datenmengen. Zusätzlich arbeitest du mit Strings, somit ist jedes Element unterschiedlich lang.
LabVIEW spezifisch ist, dass du durch die globale Variable zusätzliche Kopien im Speicher erzeugst, bei jedem "Lesevorgang" wird eine Kopie erstellt, diese wird dann verarbeitet und dann in deinem Screenshot wieder zurückgeschrieben.
Gruß, Jens
P.S.: Das Hinzufügen einer Zeile am Ende eine 2D-Array geht übrigens viel einfacher so:
[
attachment=49415]
Zwecks FGV (oder Functional Global Variable), such das mal auf ni.com...
Hallo Jens,
okay das ist ja fast so wie ich es mir gedacht habe. Das Labview Kopien bei jedem Lesevorgang erzeugt habe ich auch gerade beim Lesen im Handbuch gesehen.
Das das Hinzufügen auch ohne das Ermitteln der Arraygröße habe ich auch bei der Funktion in Array einfügen entdeckt. Danke. Wenn man das nicht direkt weiß kommt man zuerst auf andere Ideen.
So aktuell bin ich nun dazu übergegangen:
-> Keine String Daten zu speichern im Array, lieber Fließkommazahlen speichern und später umwandeln
-> Werte während Messung in Schieberegister sammeln, anschließend in globale Variable (wenn Schreibvorgang unkritisch)
So müsste es nun funktionieren
(17.04.2014 14:45 )dieseldunst schrieb: [ -> ]-> Werte während Messung in Schieberegister sammeln, anschließend in globale Variable (wenn Schreibvorgang unkritisch)
Kommt darauf an. Wenn du hier weiterhin mit "Build Array" oder "Insert Into Array" arbeitest, hast du weiterhin das Speicher-Allozier-Problem. Wenn du vorab die max. Größe der "Messung" kennst, dann lieber das Array mit "Initialize Array" vorinitialisieren und dann mit "Replace Array Subset" arbeiten.
Gruß, Jens