Forum: PC-Programmierung GNUplot beschleunigen


von Martin N. (mneumann3)


Lesenswert?

Hallo zusammen,

nachdem beim letzten mal mein Problem umgehend gelöst wurde, erhoffe ich 
mir wieder hilfreiche Hinweise.

Mein Ziel:
Datenauswertung von Messwertemüll mit GNUplot

Mein Ergebnis:
Ein GNUplot das genau das macht, was ich will.

Mein Problem:
Es dauert zu lang. Ich habe jeweils ein Ordner für einem Monat mit 8 csv 
für jeden Tag. Eine csv hat 4 MB (pro Sek. ca. 50 Werte). Zum Erstellen 
eines Multiplots braucht GNUplot über 1 min. Da ich auch noch ein paar 
Berechnungen beim plotten vorhaben, habe ich Bauchschmerzen.

Meine Hoffnung lag in der every Funktion. Aber diese verringert zwar die 
geplotteten Punkte aber es dauert genauso lange.

Wahrscheinlich liegt es an meiner inkompetenten Programmierung, da ich 
andere Sachen von GNUplot gehört habe.

reset
cd 'F:\CYDE\Geschäft (extern)\Projekte\Abwicklung\HLF 
Heberndorf\GB04-2800017\05 Dokumentation\06 Datenaufzeichnung\2017\02'
set grid x y
set tmargin 5
set bmargin 8
set lmargin 8
set rmargin 8
set key center top title " "
set title "Auswertung"
set xlabel "Zeit"
set xdata time
set xrange ["28/01/17,22:00:00":"01/03/17,05:00:00"]
set timefmt  "%d/%m/%y\",\"%H:%M:%S"
set ylabel "el. Leistung [kW]"
set y2label "TIT [°C]"
set ytics nomirror
set y2tics
set tics out
set yrange [0.0 : 500.0]
set ytics 60
set y2range [000.0 : 500.0]
set datafile separator ","
plot for [i=1:31] for [j=1:8] sprintf('%02.0f_S%02.0f_N.csv', i, j) 
using 1:8 every 10000::1::10800 title "" axes x1y1 with points pointtype 
5 pointsize 0.5 lt 3

von Sven B. (scummos)


Lesenswert?

float parsing ist für größere Datenmengen langsam, vermutlich ist das 
das größte Problem. Du kannst die Daten in ein Binärformat konvertieren 
und dann plotten (kann gnuplot).

von Martin N. (mneumann3)


Lesenswert?

float parsing? Was ist das und wo habe ich es benutzt?
Was meinst du mit Binärformat konvertieren?

von S. R. (svenska)


Lesenswert?

Deine CSV-Datei enthält ASCII-Werte, die in GNUplot als Float verwertet 
werden. Dazu muss jede Zahl von ASCII in Float gewandelt werden, was 
langsam ist.

Du kannst deine Datei auch extern umwandeln, so dass sie die Werte 
direkt binär enthält, dann hat GNUplot es einfacher und sollte deutlich 
schneller sein.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Martin N. schrieb:
> Es dauert zu lang. Ich habe jeweils ein Ordner für einem Monat mit 8 csv
> für jeden Tag. Eine csv hat 4 MB (pro Sek. ca. 50 Werte).

4 Millionen Bytes oder 4 Millionen Werte?

50 Werte/s · 86.400 s = 4.320.000 Werte

Und wie sind dieser Werte in der Datei angeordnet? In deinem Beispiel im
anderen Thread stehen mehrere Werte pro Zeile. Verteilen sich die
4.320.000 Werte auf alle Spalten oder hat die Datei gar 4.320.000 Zeilen
mit mehreren Werten pro Zeile?

> Zum Erstellen eines Multiplots braucht GNUplot über 1 min.

In deinem Gnuplot-Skript wird über 31 Tage und die 8 Dateien pro Tag
iteriert. Das wären dann 1.071.360.000 (also über eine Milliarde) Werte
oder möglicherweise sogar Datenzeilen. Die Dateien sind zusammen also
etliche GB groß. Da dauert ja je nach Festplattengeschwindigkeit allein
das Lesen der Dateien (ohne Parsen, Verarbeiten und Plotten der Daten)
schon 1 Minute.

Auf der anderen Seite sehe ich in deinem Skript ein

  every 10000::1::10800

was die Sache wiederum sehr schnell machen sollte, weil von jeder Datei
nur die ersten 10.000 Zeilen gelesen und nur zwei davon tatsächlich
geplottet werden.

von K. J. (Gast)


Lesenswert?

Hm ich hab mit CSV hier nicht solche Problem hänge mal einen ausschnitt 
an, ebenfalls mit vielen floats
1
78641 1 1491942631 14 0.4 14 0.1 14.5 0.1 14.5 0 14 0.1 14.5 4.5 32.5 0.1 4 0 115 7.6 14.8 9.3 2.1 11 13.5 11 11 11 12.5

Sind 78641 Zeilen(~15MB) die macht gnuplot in einigen sec. auf einem 
i5/8GB allerdings hab ich festgestellt das CSV Dateien ohne Separatoren 
wesentlich schneller verarbeitet werden, wird auch in den meisten FAQs 
entfohlen.

Was richtig zeit frist ist werte umrechnen im script.

von Martin N. (mneumann3)


Lesenswert?

Danke für die Antworten!
Also pro Monat habe ich tatsächlich ein GB Daten. Eine csv besteht aus 
ca. 50 Spalten mit je 10800 Einträgen. Ich will nur vier Spalten daraus 
plotten. Was mich wundert, dass die every Funktion keinen Einfluß auf 
die Dauer hat.

Wie kriege ich die Kommas denn aus der csv? Dafür müsste ich doch ein 
separates Programm schreiben, oder?
Wie wandle ich die csv in binär um? Ich kann binär mit den Fingern 
zählen. Aber das ist schon alles.

von K. J. (Gast)


Lesenswert?

Hm wie du die Trennzeichen raus bekommst weiß ich nicht ich mach das 
wenn ich meine Datenbank exportiere mit der anleitung von.

https://steffen-kockel.de/blog/mysql-nach-csv-exportieren

von Yalu X. (yalu) (Moderator)


Lesenswert?

Martin N. schrieb:
> Also pro Monat habe ich tatsächlich ein GB Daten. Eine csv besteht aus
> ca. 50 Spalten mit je 10800 Einträgen. Ich will nur vier Spalten daraus
> plotten.

Ich glaube, jetzt hab ich's verstanden.

Ich habe mal eine Testdatei mit Zufallsdaten erstellt. Sie besteht aus
10800 Zeilen der folgenden Form:

1
"06/02/17","08:16:26","  282","  272","  304","  150","   22","  155","  439","  447","  387","  495","  338","  399","   59","  326","  236","  450","  359","  420","  333","  456","  157","  107","  386","  285","  434","  260","   86","  247","  424","   70","  490","  415","  453","  275","  477","   67","  286","  341","  496","  475","  472","  140","  364","  142","  423","  130","   19","  146","  300","  464"
2
...

Die gesamte Datei ist etwa 4,5MB groß, was deinen Angaben entspricht.
Wenn ich diese Datei¹ mit deinem obigen Skript (ohne die Every-Option)
248-mal auf den Bildschirm plotten lasse, dauert das auf meinem Notebook
(i7, 2,9GHz und SSD) 10,5s. Dabei wird aber nur eine Spalte verwendet.
Erweitert man das Skript auf 4 Spalten, dauert das Ganze 41,0s, was
schon nahe bei der einen Minute liegt, die du gemessen hast.

Lässt man das Diagramm direkt in eine PNG-Datei (1920×1080) schreiben,
reduzieren sich die 41,0s auf 26,8s.

Mit einem vereinfachten Datenformat ohne die Kommata, Anführungszeichen
und füllenden Leerzeichen

1
13/02/17 14:08:53 292 189 287 170 479 191 322 384 452 499 470 315 14 384 495 483 15 235 449 139 364 64 33 317 489 77 30 436 125 121 261 240 39 255 328 102 332 262 244 324 205 386 455 394 248 165 184 3 461 372
2
...

werden nur noch 18,1s benötigt. Der Unterschied ist aber nicht so
riesig, dass es sich lohnen würde, die Originaldateien mit einem
zusätzlichen Skript in das vereinfachte Format zu konvertieren. Mit
einem Binärformat habe ich nicht getestet, da ich erst nachschauen
müsste, wie man darin die Datums- und Zeitangaben darstellt.

Aber selbst ohne Konvertierung werden immerhin 4 Millionen Datenpunkte
pro Sekunde durchgenudelt. Ich möchte nicht wissen, wie schwer sich
Excel & Co mit solchen Datenmengen tut.

Etwas Vorsicht ist geboten mit anderen Punkttypen. Mit Pointtype 6
(nichtausgefüllter Kreis) steigt die Laufzeit auf 82,4s an. Umgekehrt
sind Dots mit 16,9s noch etwas schneller als Points.

> Was mich wundert, dass die every Funktion keinen Einfluß auf die Dauer
> hat.

Bei mir hat das sehr wohl einen Einfluss: Es werden nur noch 0,75s
benötigt.

Ich frage mich ja sowieso, wie sinnvoll es ist, in ein einziges Diagramm
über 100 Millionen Datenpunkte zu plotten, da man diese visuell nicht
mehr voneinander trennen kann. Dünnt man die Daten mit "every 10" um den
Faktor 10 aus, ist das Diagramm schon in 4,1s fertig.

> Zum Erstellen eines Multiplots braucht GNUplot über 1 min.

1 Minute hört sich zwar lang an. Aber diese Rechenzeit fällt doch nur
einmal im Monat an. Muss man sich da wirklich Gedanken machen?

————————————
¹) Ich habe 248-mal dieselbe Datei genommen, was aber an der Laufzeit
   nichts ändern sollte.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.