Advertisement
Guest User

Untitled

a guest
Mar 28th, 2017
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.87 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5.  
  6.  
  7.  
  8. interface IBitStreamWriter
  9. {
  10. void SeekZero();
  11. uint ReadBits(int numbits);
  12. void WriteBits(uint value, int numbits);
  13. void FlushBits();
  14. }
  15.  
  16.  
  17. class BitStreamWriter8 : IBitStreamWriter
  18. {
  19. byte[] m_Buffer;
  20. UInt64 m_BitStage;
  21. int m_CurrentBitIdx;
  22. int m_CurrentByteIdx;
  23.  
  24. public BitStreamWriter8(int capacity)
  25. {
  26. m_Buffer = new byte[capacity];
  27. m_CurrentBitIdx = 0;
  28. m_CurrentByteIdx = 0;
  29. m_BitStage = 0;
  30. }
  31.  
  32. public void SeekZero()
  33. {
  34. m_CurrentBitIdx = 0;
  35. m_CurrentByteIdx = 0;
  36. m_BitStage = 0;
  37. }
  38.  
  39. // Write the lower numbits from value into stream.
  40. public void WriteBits(UInt32 value, int numbits)
  41. {
  42. //Debug.Assert(numbits > 0 && numbits <= 32);
  43. //Debug.Assert((UInt64.MaxValue << numbits & value) == 0);
  44.  
  45. m_BitStage |= ((UInt64)value << m_CurrentBitIdx);
  46. m_CurrentBitIdx += numbits;
  47.  
  48. while (m_CurrentBitIdx >= 8)
  49. {
  50. m_Buffer[m_CurrentByteIdx++] = (byte)(m_BitStage & 0xff);
  51. m_CurrentBitIdx -= 8;
  52. m_BitStage >>= 8;
  53. }
  54. }
  55.  
  56. // Read numbits from stream, return in lower bits
  57. public UInt32 ReadBits(int numbits)
  58. {
  59. //Debug.Assert(numbits > 0 && numbits <= 32);
  60.  
  61. while (m_CurrentBitIdx < 32)
  62. {
  63. m_BitStage |= (UInt64)m_Buffer[m_CurrentByteIdx++] << m_CurrentBitIdx;
  64. m_CurrentBitIdx += 8;
  65. }
  66.  
  67. var res = m_BitStage & (((UInt64)1 << numbits) - 1);
  68. m_BitStage >>= numbits;
  69. m_CurrentBitIdx -= numbits;
  70. return (UInt32)res;
  71. }
  72.  
  73. public void FlushBits()
  74. {
  75. if (m_CurrentBitIdx > 0)
  76. {
  77. WriteBits(0, 8 - m_CurrentBitIdx);
  78. }
  79. }
  80. }
  81.  
  82. class BitStreamWriter32 : IBitStreamWriter
  83. {
  84. UInt32[] m_Buffer;
  85. UInt64 m_BitStage;
  86. int m_CurrentBitIdx;
  87. int m_CurrentWordIdx;
  88.  
  89. // capacity must be multiple of 4
  90. public BitStreamWriter32(int capacity)
  91. {
  92. Debug.Assert((capacity % 4) == 0);
  93.  
  94. m_Buffer = new UInt32[capacity / 4];
  95. m_CurrentBitIdx = 0;
  96. m_CurrentWordIdx = 0;
  97. m_BitStage = 0;
  98. }
  99.  
  100. public void SeekZero()
  101. {
  102. m_CurrentBitIdx = 0;
  103. m_CurrentWordIdx = 0;
  104. m_BitStage = 0;
  105. }
  106.  
  107. // Write the lower numbits from value into stream.
  108. public void WriteBits(UInt32 value, int numbits)
  109. {
  110. //Debug.Assert(numbits > 0 && numbits <= 32);
  111. //Debug.Assert((UInt64.MaxValue << numbits & value) == 0);
  112.  
  113. m_BitStage |= ((UInt64)value << m_CurrentBitIdx);
  114. m_CurrentBitIdx += numbits;
  115.  
  116. if (m_CurrentBitIdx >= 32)
  117. {
  118. int outgoing = (int)(m_BitStage & 0xffffffff);
  119. m_Buffer[m_CurrentWordIdx++] = (UInt32)System.Net.IPAddress.HostToNetworkOrder(outgoing);
  120. m_CurrentBitIdx -= 32;
  121. m_BitStage >>= 32;
  122. }
  123. }
  124.  
  125. // Read numbits from stream, return in lower bits
  126. public UInt32 ReadBits(int numbits)
  127. {
  128. //Debug.Assert(numbits > 0 && numbits <= 32);
  129.  
  130. if (m_CurrentBitIdx < 32)
  131. {
  132. m_BitStage |= (UInt64)((UInt32)System.Net.IPAddress.NetworkToHostOrder((int)m_Buffer[m_CurrentWordIdx++])) << m_CurrentBitIdx;
  133. m_CurrentBitIdx += 32;
  134. }
  135.  
  136. var res = m_BitStage & (((UInt64)1 << numbits) - 1);
  137. m_BitStage >>= numbits;
  138. m_CurrentBitIdx -= numbits;
  139. return (UInt32)res;
  140. }
  141.  
  142. public void FlushBits()
  143. {
  144. if (m_CurrentBitIdx > 0)
  145. {
  146. WriteBits(0, 32 - m_CurrentBitIdx);
  147. }
  148. }
  149. }
  150.  
  151. class Program
  152. {
  153. public static void Main(string[] args)
  154. {
  155. var num_tests = 1000000;
  156.  
  157. var stream = new BitStreamWriter32(num_tests * 4);
  158. ProfileIt("Stream32", stream, num_tests);
  159.  
  160. var stream8 = new BitStreamWriter8(num_tests * 4);
  161. ProfileIt("Stream8", stream8, num_tests);
  162. }
  163.  
  164. struct TestCase
  165. {
  166. public int numbits;
  167. public UInt32 value;
  168. }
  169.  
  170. static void ProfileIt(string name, IBitStreamWriter stream, int num_tests)
  171. {
  172. Debug.Log("\n==================");
  173. Debug.Log("Profiling " + name);
  174. Debug.Log("==================");
  175. Debug.Log("Creating " + num_tests + " testcases");
  176.  
  177. var rand = new System.Random();
  178.  
  179. var bits = 0;
  180. var cases = new TestCase[num_tests];
  181. for (var i = 0; i < num_tests; i++)
  182. {
  183. cases[i].numbits = rand.Next(1, 33);
  184. bits += cases[i].numbits;
  185. cases[i].value = (UInt32)rand.Next(0, 65536) | ((UInt32)rand.Next(0, 65536) << 16);
  186. cases[i].value &= (UInt32)(((UInt64)1 << cases[i].numbits) - 1);
  187. }
  188. Debug.Log("Done");
  189.  
  190. var t = new System.Diagnostics.Stopwatch();
  191. t.Start();
  192. for (var i = 0; i < num_tests; i++)
  193. {
  194. var tc = cases[i];
  195. stream.WriteBits(tc.value, tc.numbits);
  196. }
  197. stream.FlushBits();
  198.  
  199. t.Stop();
  200. Debug.Log("Wrote " + num_tests + " ints with 1-32 bits. Total " + bits + " bits");
  201. Debug.Log("Time: " + t.ElapsedMilliseconds + " ms ("+(bits/8/1024/1024*1000/t.ElapsedMilliseconds)+") mb/s");
  202.  
  203. stream.SeekZero();
  204.  
  205. t.Reset();
  206. t.Start();
  207.  
  208. foreach (var tc in cases)
  209. {
  210. var r = stream.ReadBits(tc.numbits);
  211. //Debug.Assert(r == tc.value);
  212. }
  213. t.Stop();
  214. Debug.Log("Read " + cases.Length + " chunks");
  215. Debug.Log("Time: " + t.ElapsedMilliseconds + " ms ("+(bits/8/1024/1024*1000/t.ElapsedMilliseconds)+" mb/s)");
  216. }
  217. }
  218.  
  219.  
  220. public class BitStream : MonoBehaviour {
  221.  
  222. IEnumerator Start ()
  223. {
  224. // Wait a bit to let stuff settle
  225. Debug.developerConsoleVisible = true;
  226. yield return new WaitForSeconds(2.0f);
  227.  
  228. var args = new string[0];
  229. Program.Main(args);
  230. }
  231. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement