Laden...

Riesige Textdatei schnell einlesen und verarbeiten

Erstellt von dwoe vor 12 Jahren Letzter Beitrag vor 12 Jahren 28.686 Views
Thema geschlossen
D
dwoe Themenstarter:in
57 Beiträge seit 2010
vor 12 Jahren
Riesige Textdatei schnell einlesen und verarbeiten

Hallo zusammen,

ich stehe vor der Aufgabe sehr viele (>2000), sehr große (>80MB) Textdateien einlesen und verarbeiten zu müssen. Es handelt sich um Messergebnisse, die durchforstet werden müssen.

Die Dateien sind Textdateien - in jeder Zeile steht ein Zeitstempel mit Messwert, die ich zur weiteren Verarbeitung in eine Collection schaufeln möchte (in welche muss ich noch klären).

Zu den Fragen:
*Welche Einleseroutine ist die schnellste - auch in Hinblick auf das weitere Verarbeiten? Ich habe ReadAllLines und Streamreader getestet. *Wie durchforste ich das Eingelesene am effizientesten? Wenn ich ReadAllLines nutze kriege ich ja ein Array aus Strings, die ich mittels Substring zerlegen kann. Nur kommt mir das nicht sehr schnell vor. Gibt es andere und schnellere Möglichkeiten (ByteArray)?

Bei der Menge an Daten und Dateien kommt es schon auf ein paar Sekunden an.

Vielen Dank,

Dirk

5.657 Beiträge seit 2006
vor 12 Jahren

Hi Dirk,

die größte Performance-Steigerung hättest du sicherlich, wenn du nicht die ganze Datei einlesen müßtest, bevor du die Daten verarbeitest. Dazu müßte man aber wissen, wie die Dateien aufgebaut sind.

Christian

Weeks of programming can save you hours of planning

T
2.219 Beiträge seit 2008
vor 12 Jahren

Ich arbeite in unserer Firma an einem Projekt bei dem wir viele kleine Dateien einlesen müssen.
Die Dateien haben den CSV Aufbau mit ; als Trenner.
Dort sind ca. 15-20 Spalten, die dann in einem enstprechendes Objekt gemappt werden.

Dort arbeite ich hauptsächlich mit einem StreamReader.
Dies hat sich bei vielen Aufgaben am performantesten gezeigt.

Alternativ könnte man folgendes testen.

1.Datei als Byte Array einladen(File.ReadAllBytes).
2.Byte Array in String umwandeln(BitConverter.GetString).
3.String per \r\n auf Zeilen aufteilen(String.Split)
4.Zeilen verarbeiten.

Ob das jetzt aber schneller ist als mit einem StreamReader würde ich aber etwas bezweifeln.
Damit man dir aber helfen kann, wäre auch noch wichtig zu wissen wie dein Code bisher aussieht.

Ggf. kann man am Code selbst noch Optimierungen vornehmen.
Dort kann man immer Performance rausholen.
Alternativ empfiehlt sich bei vielen Dateien auch das arbeiten mit Threads.
Wenn du eine Methode schreibst, die per ThreadPool die Dateien verarbeitet und in einer entsprechenden Struktur per lock die Daten zusammen fügst, kannst du ordentlich Performance gewinnen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

5.657 Beiträge seit 2006
vor 12 Jahren

1.Datei als Byte Array einladen(File.ReadAllBytes).
2.Byte Array in String umwandeln(BitConverter.GetString).
3.String per \r\n auf Zeilen aufteilen(String.Split)
4.Zeilen verarbeiten.

Wie soll daurch ein Performance-Gewinn entstehen? Wenn die Daten schon zeilenweise in der Datei stehen, kann man die Daten auch zeilenweise aus der Datei lesen und dann gleich verarbeiten.

Christian

Weeks of programming can save you hours of planning

T
2.219 Beiträge seit 2008
vor 12 Jahren

Ist mir auch gerade klargeworden.
Kann also ignoriert werden.

Mein Vorschlag mit dem ThreadPool sollte aber schon einen Gewinn bringen.
Bei sauberer Umsetzung sollte es möglich sein bis zu 50% der Verarbeitungszeit zu sparen.

Kommt aber auch darauf an auf was für einem System die Auswertung läuft.
Auf einem Dual Core wird es eher ein geringer gewinn.
Bei einem Quad Core sieht es dann schon besser aus.

Mit einer entsprechenden Manager Klasse kannst du dann die Ergebnisse sammeln und später auswerten.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo T-Virus,

typischerweise ist bei sowas der Geschwindigkeit der Festplatte der Flaschenhals. Diese ist bei sequentiellen Transfers am höchstens und sinkt üblicherweise wenn mehrere Threads gleichzeitig an verschiedenen Stellen lesen. Die Verarbeitung im Speicher fällt normalerweise kaum ins Gewicht.

Hallo dwoe,

kurz gesagt, es dürfte ziemlich schuppe sein, wie du es machst, solange du die Dateien sequentiell einliest.

herbivore

6.862 Beiträge seit 2003
vor 12 Jahren

Hallo,

ich stand mal vor Ewigkeiten vor einer ähnlichen Aufgabe:
Logfiles mit Pfaden und weiteren Angaben separiert mit Semikolon. Waren ca. 5 Spalten und ca. 5 Millionen Zeilen.

Das schnellste war Zeile für Zeile zu lesen mit ReadLine und diesen String dann mit Substring anhand der Semikolons auseinanderzunehmen. Mit den Substrings wurden dann auch Objekte mit den Infos befüllt.

Warum das schnell ist: Es werden wenig temporäre Strings erzeugt, da die mit Substring erzeugten Strings ja das Datum waren für die zu erstellenden Objekte und es mussten keine großen Speicherbereiche angefordert werden da Zeile für Zeile gelesen wurde. Das ganze war in ner zehntel Sekunde durchgeparst. Mit sowas wie Regex braucht man z.B. gar nicht erst anfangen. Bei trivialen Aufbauten wie

in jeder Zeile steht ein Zeitstempel mit Messwert hat man 100 Zeilen durchgeparst bevor überhaupt nen Regexobjekt erstellt wurde.

Alternativ empfiehlt sich bei vielen Dateien auch das arbeiten mit Threads Aber nur wenn das Parsen länger als das Lesen dauert um dann nen Producer-Comsumer Muster umzusetzen. Gleichzeitig mehrere Dateien zu lesen macht keinen Sinn da die Festplatte eh schon das begrenzenden Medium ist und mehrere Leseanforderungen sich nur gegenseitig behindern da der Lesekopf ja umpositioniert werden muss. Da ist es egal wieviel Cores die CPU hat, die Festplatte ist das begrenzende Medium.

Baka wa shinanakya naoranai.

Mein XING Profil.

T
2.219 Beiträge seit 2008
vor 12 Jahren

Natürlich ist die Festplatte hier der Flaschenhals.
Wenn aber die Verarbeitung am ende mehrzeit braucht als das einlesen einer 80 MB Datei, dann kann man auch gleich mit mehreren Threads arbeiten.

Wenn die Festplatte weniger als 1 Sekunde benötigt um 80 MB zu lesen aber ca. 1 Sekunde benötigt wird die Daten zu verarbeiten, dann lohnt es sich bereits die zweite Datei einlesen zu lessen in dieser Zeit.

Bei einer 80 MB Datei würde es bestimmt schon eine kleine Verzögerung in Anspruch nehmen.
Selbst wenn die Zeitspanne 500 ms beträgt kann man Threads in Erwägung ziehen.

Diesen Ansatz würde ich aber mal testen.
Im Bestenfall spart man bei so vielen Dateien schon einiges an Zeit.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

1.820 Beiträge seit 2005
vor 12 Jahren

Hallo!

@MrSparkle:

Wie soll daurch ein Performance-Gewinn entstehen? Wenn die Daten schon zeilenweise in der Datei stehen, kann man die Daten auch zeilenweise aus der Datei lesen und dann gleich verarbeiten.

Um die Datei zeilenweise einzulesen, müsste man byte für byte einlesen, anstatt immer ganze Blöcke einzulesen, was definitiv mehr Zeit kostet.
Die Daten im Speicher byte für byte durchzuarbeiten ist auf jeden Fall schneller.

Nobody is perfect. I'm sad, i'm not nobody 🙁

1.346 Beiträge seit 2008
vor 12 Jahren

Der StreamReader nutzt intern einen Buffer und ließt Blöcke aus. Die buffergröße lässt sich einstellen und beträgt standardmäßig 1024 Bytes

Hinweis von herbivore vor 12 Jahren

...weshalb es relativ egal ist, ob man byte-weise, zeilenweise oder in einem Rutsch einliest.

T
25 Beiträge seit 2011
vor 12 Jahren

Hallo dwoe,

wow, so viele Antworten auf eine nicht spezifizierte Aufgabenstellung. Erstaunlich 😁

Generell gilt:
"Probieren geht über studieren" oder "Code schreiben, testen, einen Profiler benutzen und die relevanten Stellen optimieren"

Zu deiner Aufgabenstellung

der Aufgabe sehr viele (>2000), sehr große (>80MB) Textdateien einlesen und verarbeiten
...
Bei der Menge an Daten und Dateien kommt es schon auf ein paar Sekunden an.

Ähm, eine Sekunde mehr oder weniger ist wichtig. Gut. Aber auf was bezogen? Damit kann man erst einmal nichts anfangen.
Wir wissen auch nicht wo die Dateien liegen und ob du überhaupt jede Zeile einlesen musst.

Wenn du z.B. mit einem 54K Modem mit einer Anlage verbunden bist und über diese Leitung die Daten transportierst, dann dauert das auf Grund der geringen Transferrate eine Ewigkeit. Daher solltest du erstmal ermitteln, welche Transferrate du für die Aufgabenstellung benötigst.

1. Benötigte Transferrate bestimmen
z.B. 4000 Dateien mit je 100 MB in 10 s laden
4000 * 100 MB / 10 s =
= 40.000 MB / s
= 39 GB / s

2. Infrastruktur überprüfen und ggf. anpassen
So, liegen die Daten auf einer HDD-Festplatte auf einem normalen Rechner (ohne RAID & Co.), dann hast du evtl. ein kleines Problem. Dieses Problem gilt es zu lösen.

3. Programm erstellen
Jetzt kannst du dein Programm erstellen. Schreib es einfach mit den Kentnissen die du hast. Die C# Klassen zum lesen und schreiben von Dateien arbeiten sehr gut und besitzen in der Regel auch einen Buffer im Hintergrund.

4. Testen und Optimieren
Hier kann man noch einiges an Zeit gewinnen, falls es notwendig ist. Doch das ist erstmal nicht von interesse.

Gruß, Thomas

771 Beiträge seit 2009
vor 12 Jahren

Hi all together,

unter .NET 4 würde ich mal die Memory Mapped Files ausprobieren, denn diese sind extra zum (schnellen) Zugriff auf große Dateien ausgelegt.
Und insbesondere die Pufferung ist eigentlich der Flaschenhals beim Lesen von großen Datenmengen in modernen Systemen (da ja immer die Daten dann mehrfach kopiert werden und daher habe ich bei meinen C++ Programmen dann die Pufferung immer komplett ausgeschaltet, damit die Daten ruckzuck gelesen sind!).

D
dwoe Themenstarter:in
57 Beiträge seit 2010
vor 12 Jahren

Hallo zusammen und danke für die Antworten.

Da das Lesen der Datei wirklich nur ein kleiner Teilaspekt ist würde ich mein Frage gerne erweitern.

Welche Form der Collection sollte ich wohl verwenden um die Daten im Speicher zu halten und weiter zu verarbeiten?

Konkret geht es darum eine Zeitreihen (Wertepaar aus Datum/Uhrzeit und Wert) mit 5.000.000 Einträgen zu verwalten. Eine Anwendung wäre dann z.B. die Werte der Größe nach zu sortieren oder z.B. aus den Minuten-Werten Tages-Mittelwerte zu berechnen.

Sollte man für die Wertepaare eine Klasse oder eine Struktur wählen?

Welche Form der Collection sollte für die weitere Verarbeitung (siehe Beispiel) der Daten die schnellste sein?

Ich hoffe für die Fragestellung sind die "Anforderungen" genau genug spezifiziert...

Vielen Dank,

Dirk

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo dwoe,

welche Collection "die schnellste" ist, hängt davon ab, welche Zugriffe häufig sind. Zu jeder Collection aus dem Framework findest du bei jeder relevanten Operation über den Aufwand der Operation. Eine Übersicht gibt es in [Übersicht] Collections (Auflistungen) ab .NET Framework 2.0.

Wenn alle oder viele Werte zu verarbeiten sind, gibt es eh keine Collection mit der es richtig schnell geht.

herbivore

D
dwoe Themenstarter:in
57 Beiträge seit 2010
vor 12 Jahren

Nochmal eine prinzipielle Frage:

Wie sollte der Datentyp für das Wertepaar (Datum/Uhrzeit und Wert) aussehen? Ich habe das Gefühl, dass das Füllen der Collection 3-mal so lange dauert, wenn ich anstelle einer Structure eine Klasse definiere.

Gibt es Gründe für die Verwendung einer Klasse?

Viele Dank,

Dirk

U
1.688 Beiträge seit 2007
vor 12 Jahren

Ich habe das Gefühl, dass das Füllen der Collection 3-mal so lange dauert, wenn ich anstelle einer Structure eine Klasse definiere.

Was heißt denn "Gefühl"? "3-mal so lange" sollte sich doch wohl messen lassen.

Welche "Collection" hast Du denn nun verwendet und wie füllst Du sie?

W
872 Beiträge seit 2005
vor 12 Jahren

Structs sind "leichtgewichtiger" als Klassen - eine Struct ist ein Werttyp, eine Klasse ein Referenztyp, so dass sowohl die Werte als auch eine Referenz darauf generiert werden.
Dictionaries in C# sind sehr performant, wenn Deine Hash-Funktion gut ist.

Hinweis von herbivore vor 12 Jahren

Vielleicht "leichtgewichtiger" bei der Erstellung, dafür "schwergewichtiger" bei Zuweisung oder Parameterübergabe. Insofern kann man nicht pauschal sagen, was in der Gesamtbetrachtung schneller ist. Außerdem ist Geschwindigkeit in den meisten Fällen sowieso nicht das geeignete Kriterium, um zu entscheiden, was man wählen sollte, sondern ausschlaggebend ist die unterschiedliche Semantik (Wert- vs. Referenztyp). Das wurde schon ausführlich im Forum besprochen, z.B. in Class vs. Struct.

D
dwoe Themenstarter:in
57 Beiträge seit 2010
vor 12 Jahren

Was heißt denn "Gefühl"? "3-mal so lange" sollte sich doch wohl messen lassen.

Welche "Collection" hast Du denn nun verwendet und wie füllst Du sie?

Also, für meine Test habe ich vorerst eine List<T> genutzt und mit 5.000.000 Wertepaaren gefüllt. Bei Verwendung einer Structure dauert das 0,30 Sek - bei Verwendung einer Klasse 0,95 Sek.

Die Frage wäre jetzt, ob sich diese Zeitdifferenz auch bei weiteren Operationen auf der List ergibt oder ob es nur am Anfang beim Anlegen der ganzen Objekte einmal dazu kommt und anschließend alles gleich schnell läuft.

Wenn es nur "einmal" am Anfang länger dauert könnte ich damit leben - da ich vermute, dass die folgenden Rechenoperationen maßgeblich Zeit kosten werden.

Welche Vorteile hätte ich denn von der Verwendung von Klassen statt Strukturen?

Vielen Dank,

Dirk

W
872 Beiträge seit 2005
vor 12 Jahren

Schau mal in C# struct/class Differences.
Im Regelfall kannst Du recht leicht von Struct zu Klassen wechseln.
Ansonsten musst Du bei der Verwendung von Structs auf das sog. Boxing achten - das heisst, wenn implizit eine Struktur in eine Referenz umgewandelt wird.

5.742 Beiträge seit 2007
vor 12 Jahren

Bei Verwendung einer Structure dauert das 0,30 Sek - bei Verwendung einer Klasse 0,95 Sek. ~~Dann liegt bestimmt noch ein anderer Grund vor.
Dass ein derartiger Unterschied nur von Structs - Klassen herrührt, kann ich mir nicht vorstellen.

Evtl. hat dir auch das Windows-Eigene Disk-Caching einen Strich durch die Messung gemacht und die zweite Messung beschleunigt.~~

Habe das vorhin mal nachgemessen und erhalte ähnliche Werte wie du.

D
dwoe Themenstarter:in
57 Beiträge seit 2010
vor 12 Jahren

public class CollectionTest
{
	public class WertePaar
	{
		public System.DateTime Index;
		public long Wert;
	}

	public static void TestCollListof()
	{
		List<WertePaar> tmpColl = new List<WertePaar>();

		// Füllen
		for (i = 0; i <= 5000000; i++) {
			tmpColl.Add(new WertePaar {
				Index = new System.DateTime(i),
				Wert = i
			});
		}
	}
}

...wenn ich bei diesem Beispiel die Klasse WertePaar durch eine Strukture ersetze, dauert es statt 0,91 nur noch 0,30 Sek für die 5.000.000.

Ich lasse die Tests nicht direkt nacheinander laufen, sondern kompiliere die neue Variante ganz neu.

Vielen Dank,

Dirk

D
96 Beiträge seit 2012
vor 12 Jahren

Das kann gut sein denke ich, da Klasseninstanzen mehr Speicher verbrauchen, weil sie noch zusätzliche Headerdaten anlegen (wie z.B. eine Referenz zum zugehörigen Type). Structs hingegen verbrauchen keinen extra Platz wodurch sie schneller erstellt werden können. Der extra Speicher ist vor allem merklich, wenn du Klassen mit nur 2 Feldern benutzt.
Das dürfte aber nur beim Erstellen der Objekte eine Rolle spielen.
Du solltest nur beachten, dass Structs immer wieder kopiert werden und nicht per Referenz übergeben werden. Also wenn du sie ziemlich oft an verschiedene Methoden übergibst, kann es sein dass es etwas mehr Zeit kostet.
Sonst könntest du noch versuchen die Klasse als "sealed" zu markieren, mich würde es interessieren, ob dann Optimierungen möglich sind 😃

W
872 Beiträge seit 2005
vor 12 Jahren

Deine Aussage bezueglich der Methoden ist nicht ganz richtig - es kommt darauf an, ob die Methode by Reference oder by Value aufgerufen wird.
Falls die Methode zum Beispiel von Object kopiert wird, dann kann ein Boxing vorkommen - ansonsten kannst Du das boxing immer im IL Code nachschauen, um sicher zu sein...

D
96 Beiträge seit 2012
vor 12 Jahren

Deine Aussage bezueglich der Methoden ist nicht ganz richtig - es kommt darauf an, ob die Methode by Reference oder by Value aufgerufen wird.

Ich hab mich auf das Standardverhalten bezogen. Natürlich kann man die per Referenz übergeben. Aber gut, dass du es erwähnst, da meine Formulierung nicht eindeutig war und es zu Missverständnisses kommen könnte 😃.

Hinweis von herbivore vor 12 Jahren

Stucts sind vielleicht bei der Erstellung "leichtgewichtiger" als Klassen, dafür "schwergewichtiger" bei Zuweisung oder Parameterübergabe. Insofern kann man nicht pauschal sagen, was in der Gesamtbetrachtung schneller ist. Außerdem ist Geschwindigkeit in den meisten Fällen sowieso nicht das geeignete Kriterium, um zu entscheiden, was man wählen sollte, sondern ausschlaggebend ist im Normalfall die unterschiedliche Semantik (Wert- vs. Referenztyp). Das wurde schon ausführlich im Forum besprochen, z.B. in Class vs. Struct.

Insofern brauchen und sollten wir hier bitte nicht weiter auf die Unterschiede von Class und Struct eingehen. Das kann man alles an anderer Stelle nachlesen.

D
dwoe Themenstarter:in
57 Beiträge seit 2010
vor 12 Jahren

Was ich jetzt gerade gar nicht verstehe:

Wenn ich obiges Beispiel nutze um die List<T> mit Wertepaaren der Klasse/Struktur zu füllen, ist das Füllen mittels Struktur ja deutlich schneller (haben wir ja schon festgestellt).

Wenn ich das ganze aber mal bis zur System.OutOfMemoryException durchlaufen lasse ist bei der Structure bei 16.000.000 Elementen Schluss - bei Verwendung einer Klasse bei 33.000.000.

Woran liegt das denn? Wir hatten doch gesagt, die Klasse wäre bei kleinen Datenstrukturen speicherintensiver... oder liegt es an der unterschiedlichen Verwendung von Stack und Heap?

Danke,

Dirk

5.742 Beiträge seit 2007
vor 12 Jahren

Wenn ich das ganze aber mal bis zur System.OutOfMemoryException durchlaufen lasse ist bei der Structure bei 16.000.000 Elementen Schluss - bei Verwendung einer Klasse bei 33.000.000.

Ein Objekt kann unter der CLR maximal 2GB groß sein.
Und ich schätze mal, dass das Array in deiner Liste bei 16.000.000 zu groß wird; die Strukturen sind (speichertechnisch) ja komplett enthalten, von den Klassen hingegen ist nur ein Pointer im Array.

Verwende testweise mal ein HastSet<T> oder teile die Elemente auf mehrere Listen auf, dann sollten mehr Einträge möglich sein.
Als "Gegenprobe" kannst du die Struktur auch mal um ein weiteres Feld erweitern - dann sollte schon früher Schluss sein.

In der Praxis wirst du ja eh nie alle Elemente gleichzeitig eingelesen haben, sondern eher parallel schon mit der Verarbeitung beginnen.

W
872 Beiträge seit 2005
vor 12 Jahren

In der MS Implementierung gibt es eine maximale Objektgroesse, die u.a. auch davon abhaengt, ob Du 32 oder 64 Bit OS benutzt.
Bei der Klasse enthaelt das Objekt nur eine Referenz - also einmal 32 oder 64 bit, bei einem Struct hast Du zweimal 32 oder 64 bit dabei - also kannst Du nur die halbe Groesse abdecken - ich wuerde an Deiner Stelle einfach mal anfangen zu implementieren - wechseln zwischen Struct und Class geht meist recht schnell - nur solltest Du fuer den Class Fall Equals und GehHashCode implementieren, was Du bei Struct nicht kannst/brauchst.

5.742 Beiträge seit 2007
vor 12 Jahren

nur solltest Du fuer den Class Fall Equals und GehHashCode implementieren, was Du bei Struct nicht kannst/brauchst.

Nein, das sollte man auch bei Strukturen machen - die beiden Methoden sind bei Strukturen nur standardmäßig so implementiert, dass das Ergebnis per Reflection erzeugt wird.

S
24 Beiträge seit 2011
vor 12 Jahren

sorry für meinen offtopic post - aber der thread erinnert mich an einen lustigen "fehler", den ich als anfänger bei einer gleichartigen aufgabe zu stande gebracht habe.

ich habe zeilenweise eingelesen, wo nötig konvertiert und das ergebnis jeweils auch in der konsole ausgegeben. die laufzeit war statt sekunden/minuten so um eine stunde. es hat ewig gedauert, bis es mir dämmerte 😃

W
872 Beiträge seit 2005
vor 12 Jahren

die beiden Methoden sind bei Strukturen nur standardmäßig so implementiert, dass das Ergebnis per Reflection erzeugt wird.

Stimmt nicht ganz - siehe C# - Value Type Equals method - why does the compiler use reflection?. Aber sicher ist natuerlich selber zu implementieren...

D
dwoe Themenstarter:in
57 Beiträge seit 2010
vor 12 Jahren

In der Praxis wirst du ja eh nie alle Elemente gleichzeitig eingelesen haben, sondern eher parallel schon mit der Verarbeitung beginnen.

Hat jemand für diese Vorgehen zufällig mal ein Beispiel zur Implementierung?

Die Anforderung für ein einfaches Beispiel ist ziemlich übersichtlich:*Einlesen von > 5.000.000 Zeilen aus einer Textdatei in die List<T> mit Wertepaaren *Verarbeiten der Daten: z.B. ein gleitender Durschnitt von immer 1000 Werten

Wie könnte man so etwas implementieren, dass die Berechnung des Schnitts schon beginnt, während noch eingelesen und geparsed wird?

Viele Dank,

Dirk

S
211 Beiträge seit 2010
vor 12 Jahren

Ich denke das macht erst dann Sinn wenn du mehrere solche Textdateien hast.
D.h. während du Textdatei 2 einliest kannst du parallel schon Textdatei 1 verarbeiten.

D
dwoe Themenstarter:in
57 Beiträge seit 2010
vor 12 Jahren

Ich denke das macht erst dann Sinn wenn du mehrere solche Textdateien hast.
D.h. während du Textdatei 2 einliest kannst du parallel schon Textdatei 1 verarbeiten.

Langfristig werde ich das ja haben: ich lese mehrere Dateien ein - verarbeite sie - und nutze diese Ergebnisse dann um sie mit einer 3. Datei zu verknüpfen etc....

Daraus wird sich ein ganzer Baum mit abzuarbeitenden Aufgaben ergeben - ein parallel "Abarbeiten" wird spätestens dann sinnvoll...

Vielen Dank,

Dirk

5.657 Beiträge seit 2006
vor 12 Jahren

Hi winSharp93,

nur solltest Du fuer den Class Fall Equals und GehHashCode implementieren, was Du bei Struct nicht kannst/brauchst.
Nein, das sollte man auch bei Strukturen machen - die beiden Methoden sind bei Strukturen nur standardmäßig so implementiert, dass das Ergebnis per Reflection erzeugt wird.

Bist du dir sicher mit dieser Aussage? Oder anders gefragt, wie meinst du "per Reflection"? Der standardmäßige Vergleich von zwei Structs erfolgt byteweise, so hab ich es aus der Doku. Der HashCode wird sicherlich auf die gleiche Art berechnet, aber dazu hab ich auf die Schnelle keine genaueren Infos finden können.

Christian

Weeks of programming can save you hours of planning

T
25 Beiträge seit 2011
vor 12 Jahren

In der Praxis wirst du ja eh nie alle Elemente gleichzeitig eingelesen haben, sondern eher parallel schon mit der Verarbeitung beginnen.

Hat jemand für diese Vorgehen zufällig mal ein Beispiel zur Implementierung?

Die Anforderung für ein einfaches Beispiel ist ziemlich übersichtlich

Wenn es so übersichtlich ist, warum gibst du nicht ein Beispiel vor 🤔 Hier wird dir keiner die Aufgabe lösen oder häbchenweise servieren. Wenn du eine gezielt Frage hast, dann stell diese. Rede nicht um den heisen Brei herum in der Hoffnung, dass dir die Lösung einfällt.

Wenn ich deinen ersten Beitrag lese, dann entnehme ich

  • die Dateien sind alle gleich und strukturiert
  • einlesen der Informationen
  • verarbeiten der Informationen

Gut. Der letzte Punkt mit dem Verarbeiten ist der entscheidende Punkt.
Mach dir klar, dass du nur die Infos im Speicher haben musst, die du in den nächsten ns (nano sekunden) benötigst!

Ich möchte mich nicht wiederhollen. Bitte ließ meinen ersten Beitrag und formuliere wenn nötig eine konkrete Frage.

Wie könnte man so etwas implementieren, dass die Berechnung des Schnitts schon beginnt, während noch eingelesen und geparsed wird?

Hierzu gibt es ein paar Vorgehensweisen, die man in Büchern findet.
z.B. 2 Threads + eine Queue (abstract data type)

D
dwoe Themenstarter:in
57 Beiträge seit 2010
vor 12 Jahren

@Thomas_1:
Sorry, aber warum ignorierst Du meine Fragen nicht einfach, wenn's Dir zu blöd ist darauf zu antworten. Deine bisherigen Antworten haben zumindest mir (und wahrscheinlich auch sonst kaum jemanden) irgendwie weiter geholfen - dass 39GB/s nicht durch mein 56K-Modem passen, hätte ich glatt vorher gewusst.

Ich denke schon, mein Problem könnte so grob verstanden sein. Ich erwarte auch keine vorgekaute Lösung, sondern bin nur dankbar über grundsätzliche Tipps, wie man ein solches Problem angeht. Wenn jemand ein Codebeispiel kennt: noch besser.

Vielen Dank für Eure Hilfe,

Dirk

5.657 Beiträge seit 2006
vor 12 Jahren

Hi dwoe,

Sorry, aber warum ignorierst Du meine Fragen nicht einfach, wenn's Dir zu blöd ist darauf zu antworten.

Immer schön den Ball flachhalten! Hier beschäftigen sich Leute mit deinem Problem und du möchtest eine Lösung von uns, also sollte es vor allem in deinem Interesse liegen, den Umgangston zu wahren.

Christian

Weeks of programming can save you hours of planning

D
dwoe Themenstarter:in
57 Beiträge seit 2010
vor 12 Jahren

Ich bin wirklich super dankbar für jeden noch so kleinen Tipp und ich weiss sehr wohl, dass ich als Anfänger ohne die tolle Hilfe der Leute hier im Forum völlig aufgeschmissen wäre.

Also nochmal: vielen Dank!

(nur: mir jedes mal zu sagen, dass meine Frage zu unspezifisch ist bringt keinen weiter - die anderen scheinen mein Problemm aber ja verstanden zu haben)

Viele Grüße,

Dirk

5.742 Beiträge seit 2007
vor 12 Jahren

So - und jetzt aber bitte auch wenn ich mich nicht selber ganz dran gehalten habe 😄 wieder zurück zum Thema!

Hat jemand für diese Vorgehen zufällig mal ein Beispiel zur Implementierung?

Schaue dir z.B. mal PLINQ an; da kannst du dann Pseudocodemäßig etwas wie folgendes schreiben:


File.ReadLines(path)
   .AsParallel()
   .Select(line => line.Split(';'))
   .Select(parts => new { Name = parts[0], Value = parts[1] } ) //Oder wie auch immer
   .Average(item => item.Value); //z.B.

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo dwoe,

auch auf die Gefahr hin, dass dir das nicht gefällt. Alle Fragen in diesem Thread fallen unter [Hinweis] Wie poste ich richtig? Punkt 1.1.1 oder liegen ziemlich in der Nähe. Wenn ein Thread, der ein an sich einfaches Problem behandelt, so länglich wird, liegt das meistens - wie auch hier - an allen möglichen Nachfragen, die auf fehlende Grundlagen zurückzuführen sind.

Du hast jetzt mehr Hilfe bekommen, also du erwarten konntest und erwarten kannst. Wenn du in der Situation anfängst, nach konkreten Implementierungen zu fragen und sogar einzelne Helfer zu kritisieren, hast du den Bogen wirklich überspannt.

herbivore

Thema geschlossen