Entwickler-Ecke
Basistechnologien - Konvertieren / casten von Arrays ohne sie zu kopieren
C# - Sa 12.03.16 23:16
Titel: Konvertieren / casten von Arrays ohne sie zu kopieren
Guten Abend,
ich befürchte zwar ich kenne die Antwort schon aber ich Frage lieber nochmal.
Gibt es in C# einen Weg multidimensionale Arrays in eindimensionale Arrays zu casten oder ähnliches? Ich meine damit eine Konvertierung die das Quell-Array
nicht kopieren muss. Die Arrays sind immer vom gleichen Typ, z.B.
C#-Quelltext
1: 2:
| byte[] buffer = new buffer[100]; byte[,] newBuffer = (Some magic) buffer; |
Das Verfahren kann von mir aus auch im
unsafe Kontext arbeiten. Mir ist nur wichtig, dass das Array nicht kopiert werden muss.
Th69 - So 13.03.16 12:50
Tja, wenn du die Antwort schon kennst. ;-)
Du könntest einen Enumerator (mittels IEnumerator) schreiben, welcher aus dem mehrdimensionalen einen eindimensionalen erzeugt, so ähnlich wie SelectMany.
PS: Deine Beschreibung paßt nicht zum Code (dort ist es genau andersherum: eindimensional -> mehrdimensional)...
C# - So 13.03.16 17:22
Zitat: |
so ähnlich wie SelectMany |
Aber SelectMany erzeugt doch wieder eine neue Enumeration wenn ich es richtig verstanden habe. Bei Referenztypen wäre das ja nicht soo tragisch aber da ich auf Byte Arrays aus bin würde das doch wieder kopieren bedeuten oder nicht?
Zitat: |
Deine Beschreibung paßt nicht zum Code |
:mrgreen: Hoppla. Ja ich dachte wenn es in die eine Richtung machbar ist, ist das Ganze auch invertierbar.
Ich habe es jetzt mal so gelöst, dass ich eine Klasse um ein eindimensionales Array gebaut habe und einen mehrdimensionalen Indexer implementiert habe.
Falls noch jemand andere Ideen hat wäre ich dankbar wenn er diese hier teilen würde.
Ralf Jansen - So 13.03.16 17:51
Zitat: |
Aber SelectMany erzeugt doch wieder eine neue Enumeration wenn ich es richtig verstanden habe |
Nö. Es iteriert nur über Daten verändert diese aber nicht. Erst wenn du das System zwingst dir eine bestimmte Speicherauslegung der Daten zu geben, z.B. durch ToArray(), dann bekommst du was neues.
Ist ja auch die Antwort auf deine Frage. Ein IEnumerable<Typ> kannst du mit der passenden Implementierung wie ein IEnumerable<Typ,Typ> aussehen lassen. Es ist ja nur das Interface zu Daten. Ein Array ist aber ein bestimmter Typ mit einer bestimmten Speicherauslegung die mußt du dann halt anpacken.
Zitat: |
Ich habe es jetzt mal so gelöst, dass ich eine Klasse um ein eindimensionales Array gebaut habe und einen mehrdimensionalen Indexer implementiert habe. |
Andere Lösung habe ich nicht du musst dir nur über den ~Tausch~ denn du hier vornimmst klar sein. Die Datenstruktur zu einem Array[,] zu ändern mag teuer sein der einzelne Zugriff später schneller.
Du musst also entscheiden was die lieber ist schnelleres erzeugen, langsamerer Zugriff oder langsameres erzeugen, schnellerer Zugriff. ~Best of both worlds~ gibts nicht.
C# - So 13.03.16 19:02
Ah okay. Danke für die Aufklärung. Mein Problem ist nicht, dass die Konvertierung bremsen würde, sondern dass der Speicher überläuft. Ich muss sehr große Datenmengen verarbeiten, die teilweise auch nicht komplett in den Speicher passen. Das bedeutet wiederum, dass ich die Daten partitioniert laden und verarbeiten muss. Und wenn ich dann Datenstruktren von mehreren Gigabyte kopieren muss ist das sicherlich auch nicht optimal.
Die Frage wäre jetzt: was ist schneller? Den ganzen Datenblock zu kopieren oder immer Offsets beim Zugriff hinzuzurechnen?
Kann mir jemand was zur Performance von Enumerator sagen? Sind Zugriffe damit schneller im Vergleich zum Offset-Index Zugriff, bzw. wäre unter der Haube da überhaupt ein Unterschied in der Arbeitsweise?
Ralf Jansen - So 13.03.16 19:47
Zitat: |
Kann mir jemand was zur Performance von Enumerator sagen? Sind Zugriffe damit schneller im Vergleich zum Offset-Index Zugriff, bzw. wäre unter der Haube da überhaupt ein Unterschied in der Arbeitsweise? |
Du gibst den richtigen Hinweis "unter der Haube". Wie gut der ist hängt halt von der Qualität deiner Implementierung ab und von der Art/Häufigkeit welcher Zugriffe.
Wenn wir uns im Rahmen deiner angesprochenen Umgebung befinden also Datenmengen die nicht komplett in den Speicher passen dann geht es bestimmt eher um die Lösung hinter den Kulissen und weniger ob das ein direkt angesprochenes Array ein irgendwie gearteter Enumerable oder was auch immer ist die als Außendarstellung der Implementierung genutzt wird.
Ich würde das Problem mit den Fragen angehen was die Quelle(n) der Daten ist insbesondere was für einen Zugriff es darauf gibt(eher sequentiell oder random).
C# - So 13.03.16 20:47
Zitat: |
Ich würde das Problem mit den Fragen angehen was die Quelle(n) der Daten ist insbesondere was für einen Zugriff es darauf gibt(eher sequentiell oder random). |
Ich muss die Daten aufbereiten und dafür ist für meine Fälle ein zwei- oder dreidimensionales Byte-Array am Besten. Die Daten erhalte ich über eine API (Blackbox) in Form eines eindimensionalen Byte-Arrays. Die Aufbereitung arbeitet komplett sequentiell, also der Datenstrom wird mehrmals von vorne nach hinten durchlaufen. Später soll dann noch paralleler Zugriff implementiert werden um die Performance zu steigern, aber jeder Task arbeitet dann innerhalb seines Bereiches sequentiell.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!