/// <summary> /// Get a raw value out of a larger data block. /// </summary> /// <param name="dataBlock">Data block to read from.</param> /// <param name="dataLength">Data block length.</param> /// <param name="offset">Raw value offset within data block.</param> /// <param name="length">Raw value length.</param> public void GetRawValueFromDataBlock(object dataBlock, int dataLength, int offset, int length) { var union = new UnionArray() { Bytes = (byte[])dataBlock }; if (offset >= dataLength || (offset + length) >= dataLength) { return; } Buffer.BlockCopy((byte[])dataBlock, 2 + offset, union.Bytes, 0, length); if (isBigEndian) { Array.Reverse(union.Bytes, 0, 2); } rawValue = union.Shorts[0]; }
/// <summary> /// Get a raw value out of a larger data block. /// </summary> /// <param name="dataBlock">Data block to read from.</param> /// <param name="dataLength">Data block length.</param> /// <param name="offset">Raw value offset within data block.</param> /// <param name="length">Raw value length.</param> public void GetRawValueFromDataBlock(object dataBlock, int dataLength, int offset, int length) { var union = new UnionArray() { Bytes = (byte[])dataBlock }; if (offset >= dataLength || (offset + length) >= dataLength) { return; } if (displayFormat.CompareTo("s") == 0) { displayValue = Encoding.ASCII.GetString((byte[])dataBlock); rawValue = 0; } else { Buffer.BlockCopy((byte[])dataBlock, 2 + offset, union.Bytes, 0, length); rawValue = union.Shorts[0]; } }
public void setPoints(byte[] receivedBytes, int step, uint newid, int size) { pointsH = new List <Vector3>(); colorsH = new List <Color>(); indH = new List <int>(); pointsL = new List <Vector3>(); indL = new List <int>(); colorsL = new List <Color>(); UnionArray rec = new UnionArray { Bytes = receivedBytes }; if (newid > id) { id = newid; for (int a = 0; a < 4; a++) { lowres_cloud[a] = new Mesh(); highres_cloud[a] = new Mesh(); } highres_nclouds = 0; lowres_nclouds = 0; l = 0; h = 0; pointCount = 0; countPack = 0; } else if (newid == id) { countPack++; pointsL.AddRange(lowres_cloud[lowres_nclouds].vertices); colorsL.AddRange(lowres_cloud[lowres_nclouds].colors); indL.AddRange(lowres_cloud[lowres_nclouds].GetIndices(0)); pointsH.AddRange(highres_cloud[highres_nclouds].vertices); colorsH.AddRange((highres_cloud[highres_nclouds].colors)); indH.AddRange(highres_cloud[highres_nclouds].GetIndices(0)); l = pointsL.Count; h = pointsH.Count; } else { Debug.Log("Old packet" + newid); return; } float x, y, z; byte r, g, b; for (int i = step; i < size; i += 16) // Each point is represented by 16 bytes. { try { if (i + 15 > receivedBytes.Length) { break; // Insurance. } int floatindex = (int)(i / 4.0); x = rec.Floats[floatindex]; y = rec.Floats[floatindex + 1]; z = rec.Floats[floatindex + 2]; r = receivedBytes[i + 12]; // r g = receivedBytes[i + 13]; // g b = receivedBytes[i + 14]; // b Vector3 pos = posBucket[pointCount]; pos.Set(x, y, z); Color c = colBucket[pointCount++]; c.r = (float)r / 255; c.g = (float)g / 255; c.b = (float)b / 255; if (receivedBytes[i + 15] == 1)// If it's a HR point, save it to the high resolution points. { pointsH.Add(pos); colorsH.Add(c); indH.Add(h++); } else { pointsL.Add(pos); colorsL.Add(c); indL.Add(l++); } if (h == 65000) { highres_cloud[highres_nclouds].vertices = pointsH.ToArray(); highres_cloud[highres_nclouds].colors = colorsH.ToArray(); highres_cloud[highres_nclouds].SetIndices(indH.ToArray(), MeshTopology.Points, 0); h = 0; pointsH = new List <Vector3>(); colorsH = new List <Color>(); indH = new List <int>(); highres_nclouds++; } if (l == 65000) { lowres_cloud[lowres_nclouds].vertices = pointsL.ToArray(); lowres_cloud[lowres_nclouds].colors = colorsL.ToArray(); lowres_cloud[lowres_nclouds].SetIndices(indL.ToArray(), MeshTopology.Points, 0); l = 0; pointsL = new List <Vector3>(); indL = new List <int>(); colorsL = new List <Color>(); lowres_nclouds++; } } catch (System.Exception exc) { Debug.Log("Reached out of the array: " + exc.StackTrace); } } highres_cloud[highres_nclouds].vertices = pointsH.ToArray(); highres_cloud[highres_nclouds].colors = colorsH.ToArray(); highres_cloud[highres_nclouds].SetIndices(indH.ToArray(), MeshTopology.Points, 0); lowres_cloud[lowres_nclouds].vertices = pointsL.ToArray(); lowres_cloud[lowres_nclouds].colors = colorsL.ToArray(); lowres_cloud[lowres_nclouds].SetIndices(indL.ToArray(), MeshTopology.Points, 0); }
unsafe static void Main(string[] args) { Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; byte[] rawData = new byte[10000000]; new Random().NextBytes(rawData); Stopwatch sw1 = Stopwatch.StartNew(); short[] shorts = new short[rawData.Length / 2]; short[] channel1 = new short[rawData.Length / 4]; short[] channel2 = new short[rawData.Length / 4]; System.Buffer.BlockCopy(rawData, 0, shorts, 0, rawData.Length); for (int i = 0, j = 0; i < shorts.Length; i += 2, ++j) { channel1[j] = shorts[i]; channel2[j] = shorts[i + 1]; } sw1.Stop(); Stopwatch sw2 = Stopwatch.StartNew(); short[] channel1b = new short[rawData.Length / 4]; short[] channel2b = new short[rawData.Length / 4]; for (int i = 0, j = 0; i < rawData.Length; i += 4, ++j) { channel1b[j] = BitConverter.ToInt16(rawData, i); channel2b[j] = BitConverter.ToInt16(rawData, i + 2); } sw2.Stop(); Stopwatch sw3 = Stopwatch.StartNew(); short[] shortsc = new UnionArray { Bytes = rawData }.Shorts; short[] channel1c = new short[rawData.Length / 4]; short[] channel2c = new short[rawData.Length / 4]; for (int i = 0, j = 0; i < shorts.Length; i += 2, ++j) { channel1c[j] = shortsc[i]; channel2c[j] = shortsc[i + 1]; } sw3.Stop(); Stopwatch sw4 = Stopwatch.StartNew(); short[] channel1d = new short[rawData.Length / 4]; short[] channel2d = new short[rawData.Length / 4]; for (int i = 0, j = 0; i < rawData.Length; i += 4, ++j) { channel1d[j] = (short)((short)(rawData[i + 1]) << 8 | (short)rawData[i]); channel2d[j] = (short)((short)(rawData[i + 3]) << 8 | (short)rawData[i + 2]); //Equivalent warning-less version //channel1d[j] = (short)(((ushort)rawData[i + 1]) << 8 | (ushort)rawData[i]); //channel2d[j] = (short)(((ushort)rawData[i + 3]) << 8 | (ushort)rawData[i + 2]); } sw4.Stop(); Stopwatch sw5 = Stopwatch.StartNew(); short[] channel1e = new short[rawData.Length / 4]; short[] channel2e = new short[rawData.Length / 4]; fixed(byte *pRawData = rawData) fixed(short *pChannel1 = channel1e) fixed(short *pChannel2 = channel2e) { byte * pRawData2 = pRawData; short *pChannel1b = pChannel1; short *pChannel2b = pChannel2; for (int i = 0; i < rawData.Length; i += 4) { (*(pChannel1b++)) = *((short *)pRawData2); pRawData2 += sizeof(short); (*(pChannel2b++)) = *((short *)pRawData2); pRawData2 += sizeof(short); } } sw5.Stop(); Stopwatch sw6 = Stopwatch.StartNew(); short[] shortse = new short[rawData.Length / 2]; short[] channel1f = new short[rawData.Length / 4]; short[] channel2f = new short[rawData.Length / 4]; System.Buffer.BlockCopy(rawData, 0, shortse, 0, rawData.Length); System.Threading.Tasks.Parallel.For(0, shortse.Length / 2, (i) => { channel1f[i] = shortse[i * 2]; channel2f[i] = shortse[i * 2 + 1]; }); sw6.Stop(); if (!channel1.SequenceEqual(channel1b) || !channel1.SequenceEqual(channel1c) || !channel1.SequenceEqual(channel1d) || !channel1.SequenceEqual(channel1e) || !channel1.SequenceEqual(channel1f)) { throw new Exception(); } if (!channel2.SequenceEqual(channel2b) || !channel2.SequenceEqual(channel2c) || !channel2.SequenceEqual(channel2d) || !channel2.SequenceEqual(channel2e) || !channel2.SequenceEqual(channel2f)) { throw new Exception(); } Console.WriteLine("Original: {0}ms", sw1.ElapsedMilliseconds); Console.WriteLine("BitConverter: {0}ms", sw2.ElapsedMilliseconds); Console.WriteLine("Super-unsafe struct: {0}ms", sw3.ElapsedMilliseconds); Console.WriteLine("PVitt shifts: {0}ms", sw4.ElapsedMilliseconds); Console.WriteLine("unsafe VirtualBlackFox: {0}ms", sw5.ElapsedMilliseconds); Console.WriteLine("TPL: {0}ms", sw6.ElapsedMilliseconds); Console.ReadKey(); return; }
unsafe static void Main(string[] args) { Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; byte[] rawData = new byte[10000000]; new Random().NextBytes(rawData); Stopwatch sw1 = Stopwatch.StartNew(); short[] shorts = new short[rawData.Length / 2]; short[] channel1 = new short[rawData.Length / 4]; short[] channel2 = new short[rawData.Length / 4]; System.Buffer.BlockCopy(rawData, 0, shorts, 0, rawData.Length); for (int i = 0, j = 0; i < shorts.Length; i += 2, ++j) { channel1[j] = shorts[i]; channel2[j] = shorts[i + 1]; } sw1.Stop(); Stopwatch sw2 = Stopwatch.StartNew(); short[] channel1b = new short[rawData.Length / 4]; short[] channel2b = new short[rawData.Length / 4]; for (int i = 0, j = 0; i < rawData.Length; i += 4, ++j) { channel1b[j] = BitConverter.ToInt16(rawData, i); channel2b[j] = BitConverter.ToInt16(rawData, i + 2); } sw2.Stop(); Stopwatch sw3 = Stopwatch.StartNew(); short[] shortsc = new UnionArray { Bytes = rawData }.Shorts; short[] channel1c = new short[rawData.Length / 4]; short[] channel2c = new short[rawData.Length / 4]; for (int i = 0, j = 0; i < shorts.Length; i += 2, ++j) { channel1c[j] = shortsc[i]; channel2c[j] = shortsc[i + 1]; } sw3.Stop(); Stopwatch sw4 = Stopwatch.StartNew(); short[] channel1d = new short[rawData.Length / 4]; short[] channel2d = new short[rawData.Length / 4]; for (int i = 0, j = 0; i < rawData.Length; i += 4, ++j) { channel1d[j] = (short)((short)(rawData[i + 1]) << 8 | (short)rawData[i]); channel2d[j] = (short)((short)(rawData[i + 3]) << 8 | (short)rawData[i + 2]); } sw4.Stop(); Stopwatch sw5 = Stopwatch.StartNew(); short[] channel1e = new short[rawData.Length / 4]; short[] channel2e = new short[rawData.Length / 4]; fixed(byte *pRawData = rawData) fixed(short *pChannel1 = channel1e) fixed(short *pChannel2 = channel2e) { byte * pRawData2 = pRawData; short *pChannel1b = pChannel1; short *pChannel2b = pChannel2; for (int i = 0; i < rawData.Length; i += 4) { (*(pChannel1b++)) = *((short *)pRawData2); pRawData2 += sizeof(short); (*(pChannel2b++)) = *((short *)pRawData2); pRawData2 += sizeof(short); } } sw5.Stop(); if (!channel1.SequenceEqual(channel1b) || !channel1.SequenceEqual(channel1c) || !channel1.SequenceEqual(channel1d) || !channel1.SequenceEqual(channel1e)) { throw new Exception(); } if (!channel2.SequenceEqual(channel2b) || !channel2.SequenceEqual(channel2c) || !channel2.SequenceEqual(channel2d) || !channel2.SequenceEqual(channel2e)) { throw new Exception(); } Console.WriteLine(sw1.ElapsedMilliseconds); Console.WriteLine(sw2.ElapsedMilliseconds); Console.WriteLine(sw3.ElapsedMilliseconds); Console.WriteLine(sw4.ElapsedMilliseconds); Console.WriteLine(sw5.ElapsedMilliseconds); Console.ReadKey(); return; }