Autor |
Beitrag |
C#
Beiträge: 561
Erhaltene Danke: 65
Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
|
Verfasst: Sa 12.03.16 23:16
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.
_________________ Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
Zuletzt bearbeitet von C# am So 13.03.16 17:23, insgesamt 1-mal bearbeitet
|
|
Th69
Beiträge: 4777
Erhaltene Danke: 1054
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: 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)...
Für diesen Beitrag haben gedankt: C#
|
|
C#
Beiträge: 561
Erhaltene Danke: 65
Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
|
Verfasst: 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 |
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.
_________________ Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: 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.
Für diesen Beitrag haben gedankt: C#
|
|
C#
Beiträge: 561
Erhaltene Danke: 65
Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
|
Verfasst: 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?
_________________ Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: 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#
Beiträge: 561
Erhaltene Danke: 65
Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
|
Verfasst: 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.
_________________ Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
|
|
|