Wenn dein Problem oder deine Frage geklärt worden ist, markiere den Beitrag als "Lösung",
indem du auf den "Lösung" Button rechts unter dem entsprechenden Beitrag klickst. Vielen Dank!
' schrieb:Wenn eg genug Speicher hat, würde ich die Datei vorher komplett auslesen und das Parsen (die Schlaufe) wird noch schneller ohne das Datei lesen.
Das ist ein guter Vorschlag: Umstellen von automatischem Filestream auf selbstgemachtes U8-Array-Auslesen: File in U8-Array einlesen. U8-Array über Index, der hochgezählt wird, auslesen. Dann steigt zwar die Komplexität des eigenen Sourcecodes, sollte aber um einiges schneller sein als Filestream.
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
28.11.2008, 21:33 (Dieser Beitrag wurde zuletzt bearbeitet: 28.11.2008 21:33 von eg.)
' schrieb:Das Problem ist, dass ich nicht genau weiss mit wie vielen Werten ich meine Arrays vorinitialisieren soll. Evtl. kann man es aus der Dateigröße ausrechnen, aber einfach ist es nicht, da ich unterschiedliche Pakete mit unterschiedlichen Frequenzen (also zufälliges Vorkommen) im File habe. Wenn die Pakete von einem Typ wären, dann ginge es einfach.
In dem Falle mache ich es meist so dass ich mit einer gewissen Grösse beginne, diese Grösse zusammen mit dem aktuellen Pointer (Index) in einem Schieberegister abspeichere und dann jeweils vor dem Einfügen diesen Pointer mit der Grösse vergleiche. Wenn (Pointer >= Size) dann verdopple ich das array und danach kommt immer ein Replace Array Element. Am Schluss wie schon vorgestellt das Array auf die richtige Länge abkappen.
In früheren LabVIEW Versionen brachte sowas in einem Szenario wie hier von dir vorgegeben eine signifikante Laufzeitverbesserung. Vielleicht dass das in LabVIEW >= 8.5 nicht mehr so enorm ist. Natürlich immer vorausgesetzt Du hast ein paar tausend Arrayelemente. Wegen 10 mal Build Array bricht die Laufzeit noch lange nicht zusammen.
' schrieb:Würde ich nicht so machen, das ist eher eine Speicherverwendungsoptimierung und bremmst deine Schlaufe aus.
Du wolltest es ja möglichst schnell haben.
Auch wer C (oder Delphi) programmiert kann den falschen Ansatz wählen
Also mit einer jeweiligen Verdopplung des Arrays ist die Anzahl der Resizes sowas von minim, dass das kaum ins Gewicht fallen sollte. Ich bevorzuge ein paar ms zu Verschwenden um nicht für den Worstcase 100MB grosse Arrays anlegen zu müssen die dann auf wenige MB reduziert werden müssen. Die daraus resultierende Speicherauslastung kann das Programm im Endeffekt sogar langsamer machen als die (exponentielle) Vergrösserung des Arrays zwischendurch.
' schrieb:Z.B Schieberegister: Ja, optisch im Blockbild sieht es natürlich so aus, daß bei einem Schieberegister immer alles nach vorn - nach hinten -nach vorn ... geschaufelt wird. Ich bezweifle nur, daß das in der internen programmtechnischen Realisierung überhaupt so ist, dann wenn es wirklich so wäre, dann müßten Schieberegister um ein Vielfaches langsamer sein als sie es in Wirklichkeit sind. Die Geschwindigkeit von Schieberegistern ist doch bei jedem Programm wirklich das Allerletzte, um was man sich Sorgen machen muß.
Schieberegister sind in LabVIEW seit mindestens Version 6 sowas von optimalisiert. Da wird nichts unnötiges rumkopiert (abgesehen von ein paar dummen Bugs in sehr kurzlebigen Maintenance Releases wie etwa 6.0.1 einer war). Im Prinzip hat LabVIEW schon damals soviel möglich Inplace gearbeitet. Die seit 8.5 verfügbaren Inplace Funktionen fügten da nur Nuancen hinzu indem man dem LabVIEW Compiler damit explizit einen Hint geben kann, dass er eine bestimmte Operation ja ganz sicher Inplace ausführen soll. Davor konnte es bei unglücklichem Wiring schon mal passieren dass der Compiler auf Nummer sicher ging und einen Buffer mehr als nötig kopierte aber das waren schon in Version 6 die Ausnahmen mit komplexem Wirebranching und so, wo der Analyser einfach irgendeinmal das Handtuch warf und sich sagte, na dann tun wir es mal auf die sichere Weise.
' schrieb:Schieberegister sind in LabVIEW seit mindestens Version 6 sowas von optimalisiert.
Danke für diese Information, genau so hatte ich das schon vermutet.
Ich staune auch, wie schnell die Funktion "Array umkehren" ist. Nach meiner Vorstellung müssen dort bei 1000 Elementen 500 Paare getauscht werden, und trotzdem ist es rasend schnell.
Gerade heute habe ich wieder etwas entdeckt: ein binäre File ganz einlesen kann man beschleunigen, wenn man nicht als Anzahl der Bytes "-1" (= alle) anschließt, sondern erst das VI für die Anzahl der Bytes aufruft, und dann diese Anzahl an das Read-VI anschließt.
Grüße Ludwig
Anzeige
07.12.2008, 21:11 (Dieser Beitrag wurde zuletzt bearbeitet: 07.12.2008 21:12 von rolfk.)
' schrieb:Danke für diese Information, genau so hatte ich das schon vermutet.
Ich staune auch, wie schnell die Funktion "Array umkehren" ist. Nach meiner Vorstellung müssen dort bei 1000 Elementen 500 Paare getauscht werden, und trotzdem ist es rasend schnell.
Gerade heute habe ich wieder etwas entdeckt: ein binäre File ganz einlesen kann man beschleunigen, wenn man nicht als Anzahl der Bytes "-1" (= alle) anschließt, sondern erst das VI für die Anzahl der Bytes aufruft, und dann diese Anzahl an das Read-VI anschließt.
Grüße Ludwig
LabVIEW kennt intern etwas dass bei NI SubArray genannt wird. Dass ist ein spezieller Datentype der nur einen Pointer auf ein Array enthält sowie Informationen über die Anordnung der Daten darin. Bei 1D Arrays etwa sowas wie Stride (Interval), Length und Direction. Wenn Du also dann "Invers Array" machst wird eigentlich nur ein Subarray angelegt, diesem der Pointer auf das originale Array zugewiesen und das Direction Inversed Flag gesetzt. Alle Array Funktionen sind dann so schlau um bei Subarrays die Indexierung entsprechend anzupassen. Natürlich funktioniert das nur solange die Subarrays innerhalb von LabVIEW bleiben. Bei schreiben nach Disk, Flattenen oder beim übergeben des Arrays an eine DLL fällt das effektive kopieren halt trotzdem an.
Dasselbe passiert beispielsweise bei 2D Arrays wenn sie transposed werden. Subarray angelegt, pointer auf originales Array übergeben und trasnposed Flag gesetzt et voila, 500MB Daten in weniger als 1ms transposed .
Eine autoindexing Loop oder ein Arrayindex passt dann einfach die Indexberechnung an und funktioniert immer noch korrekt. Funktioniert beispielsweise gewaltig wenn man ein 2D Array transposen muss um in einer autoindex Loop die innere Dimension zu veränderen und danach wieder alles zurücktransposed. Effektiv wird nichts transposed sondern nur der autoindexing Loop ein anderes Indexing vorgegeben.
' schrieb:Dasselbe passiert beispielsweise bei 2D Arrays wenn sie transposed werden. Subarray angelegt, pointer auf originales Array übergeben und trasnposed Flag gesetzt et voila, 500MB Daten in weniger als 1ms transposed .
Eine autoindexing Loop oder ein Arrayindex passt dann einfach die Indexberechnung an und funktioniert immer noch korrekt. Funktioniert beispielsweise gewaltig wenn man ein 2D Array transposen muss um in einer autoindex Loop die innere Dimension zu veränderen und danach wieder alles zurücktransposed. Effektiv wird nichts transposed sondern nur der autoindexing Loop ein anderes Indexing vorgegeben.
Das ist doch mal eine Information. Damit kann ich was anfangen.
Danke, Rolf !
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).