Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>There is a way which avoids memory copying and iteration.</p> <p>You can use a really ugly hack to temporary change your array to another type using (unsafe) memory manipulation.</p> <p>I tested this hack in both 32 &amp; 64 bit OS, so it should be portable.</p> <p>The source + sample usage is maintained at <a href="https://gist.github.com/1050703" rel="noreferrer">https://gist.github.com/1050703</a> , but for your convenience I'll paste it here as well:</p> <pre><code>public static unsafe class FastArraySerializer { [StructLayout(LayoutKind.Explicit)] private struct Union { [FieldOffset(0)] public byte[] bytes; [FieldOffset(0)] public float[] floats; } [StructLayout(LayoutKind.Sequential, Pack = 1)] private struct ArrayHeader { public UIntPtr type; public UIntPtr length; } private static readonly UIntPtr BYTE_ARRAY_TYPE; private static readonly UIntPtr FLOAT_ARRAY_TYPE; static FastArraySerializer() { fixed (void* pBytes = new byte[1]) fixed (void* pFloats = new float[1]) { BYTE_ARRAY_TYPE = getHeader(pBytes)-&gt;type; FLOAT_ARRAY_TYPE = getHeader(pFloats)-&gt;type; } } public static void AsByteArray(this float[] floats, Action&lt;byte[]&gt; action) { if (floats.handleNullOrEmptyArray(action)) return; var union = new Union {floats = floats}; union.floats.toByteArray(); try { action(union.bytes); } finally { union.bytes.toFloatArray(); } } public static void AsFloatArray(this byte[] bytes, Action&lt;float[]&gt; action) { if (bytes.handleNullOrEmptyArray(action)) return; var union = new Union {bytes = bytes}; union.bytes.toFloatArray(); try { action(union.floats); } finally { union.floats.toByteArray(); } } public static bool handleNullOrEmptyArray&lt;TSrc,TDst&gt;(this TSrc[] array, Action&lt;TDst[]&gt; action) { if (array == null) { action(null); return true; } if (array.Length == 0) { action(new TDst[0]); return true; } return false; } private static ArrayHeader* getHeader(void* pBytes) { return (ArrayHeader*)pBytes - 1; } private static void toFloatArray(this byte[] bytes) { fixed (void* pArray = bytes) { var pHeader = getHeader(pArray); pHeader-&gt;type = FLOAT_ARRAY_TYPE; pHeader-&gt;length = (UIntPtr)(bytes.Length / sizeof(float)); } } private static void toByteArray(this float[] floats) { fixed(void* pArray = floats) { var pHeader = getHeader(pArray); pHeader-&gt;type = BYTE_ARRAY_TYPE; pHeader-&gt;length = (UIntPtr)(floats.Length * sizeof(float)); } } } </code></pre> <p>And the usage is:</p> <pre><code>var floats = new float[] {0, 1, 0, 1}; floats.AsByteArray(bytes =&gt; { foreach (var b in bytes) { Console.WriteLine(b); } }); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload