Advertisement
Guest User

Untitled

a guest
Jul 21st, 2017
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.34 KB | None | 0 0
  1. using BenchmarkDotNet.Attributes;
  2. using BenchmarkDotNet.Running;
  3. using System;
  4. using System.Runtime.InteropServices;
  5.  
  6. // A: int, string, bool の Union
  7. // B: int, long, DateTime, string, Uri の Union
  8.  
  9. public enum AType
  10. {
  11. Int32,
  12. String,
  13. Bool,
  14. }
  15.  
  16. public enum BType
  17. {
  18. Int32,
  19. Int64,
  20. DateTime,
  21. String,
  22. Uri,
  23. }
  24.  
  25. namespace SubClass
  26. {
  27. public abstract class A
  28. {
  29. public abstract AType Type { get; }
  30. protected A() { }
  31. public class AInt32 : A { public int Value; public override AType Type => AType.Int32; }
  32. public class AString : A { public string Value; public override AType Type => AType.String; }
  33. public class ABool : A { public bool Value; public override AType Type => AType.Bool; }
  34.  
  35. public static A New(int x) => new AInt32 { Value = x };
  36. public static A New(string x) => new AString { Value = x };
  37. public static A New(bool x) => new ABool { Value = x };
  38.  
  39. public static explicit operator int(A x) => ((AInt32)x).Value;
  40. public static explicit operator string(A x) => ((AString)x).Value;
  41. public static explicit operator bool(A x) => ((ABool)x).Value;
  42. }
  43.  
  44. public abstract class B
  45. {
  46. public abstract BType Type { get; }
  47. protected B() { }
  48. public class BInt32 : B { public int Value; public override BType Type => BType.Int32; }
  49. public class BInt64 : B { public long Value; public override BType Type => BType.Int64; }
  50. public class BDateTime : B { public DateTime Value; public override BType Type => BType.DateTime; }
  51. public class BString : B { public string Value; public override BType Type => BType.String; }
  52. public class BUri : B { public Uri Value; public override BType Type => BType.Uri; }
  53.  
  54. public static B New(int x) => new BInt32 { Value = x };
  55. public static B New(long x) => new BInt64 { Value = x };
  56. public static B New(DateTime x) => new BDateTime { Value = x };
  57. public static B New(string x) => new BString { Value = x };
  58. public static B New(Uri x) => new BUri { Value = x };
  59.  
  60. public static explicit operator int(B x) => ((BInt32)x).Value;
  61. public static explicit operator long(B x) => ((BInt64)x).Value;
  62. public static explicit operator DateTime(B x) => ((BDateTime)x).Value;
  63. public static explicit operator string(B x) => ((BString)x).Value;
  64. public static explicit operator Uri(B x) => ((BUri)x).Value;
  65. }
  66. }
  67.  
  68. namespace ObjectOnly
  69. {
  70. public struct A
  71. {
  72. private object _value;
  73.  
  74. public AType Type
  75. => _value is int ? AType.Int32 :
  76. _value is string ? AType.String :
  77. AType.Bool;
  78.  
  79. public static A New(int x) => new A { _value = x };
  80. public static A New(string x) => new A { _value = x };
  81. public static A New(bool x) => new A { _value = x };
  82.  
  83. public static explicit operator int(A x) => (int)x._value;
  84. public static explicit operator string(A x) => (string)x._value;
  85. public static explicit operator bool(A x) => (bool)x._value;
  86. }
  87.  
  88. public struct B
  89. {
  90. private object _value;
  91.  
  92. public BType Type
  93. => _value is int ? BType.Int32 :
  94. _value is long ? BType.Int64 :
  95. _value is DateTime ? BType.DateTime :
  96. _value is string ? BType.String :
  97. BType.Uri;
  98.  
  99. public static B New(int x) => new B { _value = x };
  100. public static B New(long x) => new B { _value = x };
  101. public static B New(DateTime x) => new B { _value = x };
  102. public static B New(string x) => new B { _value = x };
  103. public static B New(Uri x) => new B { _value = x };
  104.  
  105. public static explicit operator int(B x) => (int)x._value;
  106. public static explicit operator long(B x) => (long)x._value;
  107. public static explicit operator DateTime(B x) => (DateTime)x._value;
  108. public static explicit operator string(B x) => (string)x._value;
  109. public static explicit operator Uri(B x) => (Uri)x._value;
  110. }
  111. }
  112.  
  113. namespace ObjectEnum
  114. {
  115. public struct A
  116. {
  117. private object _value;
  118. public AType Type { get; }
  119.  
  120. public A(object value, AType type)
  121. {
  122. _value = value;
  123. Type = type;
  124. }
  125.  
  126. public static A New(int x) => new A(x, AType.Int32);
  127. public static A New(string x) => new A(x, AType.String);
  128. public static A New(bool x) => new A(x, AType.Bool);
  129.  
  130. public static explicit operator int(A x) => (int)x._value;
  131. public static explicit operator string(A x) => (string)x._value;
  132. public static explicit operator bool(A x) => (bool)x._value;
  133. }
  134.  
  135. public struct B
  136. {
  137. private object _value;
  138.  
  139. public BType Type { get; }
  140.  
  141. public B(object value, BType type) : this()
  142. {
  143. _value = value;
  144. Type = type;
  145. }
  146.  
  147. public static B New(int x) => new B(x, BType.Int32);
  148. public static B New(long x) => new B(x, BType.Int64);
  149. public static B New(DateTime x) => new B(x, BType.DateTime);
  150. public static B New(string x) => new B(x, BType.String);
  151. public static B New(Uri x) => new B(x, BType.Uri);
  152.  
  153. public static explicit operator int(B x) => (int)x._value;
  154. public static explicit operator long(B x) => (long)x._value;
  155. public static explicit operator DateTime(B x) => (DateTime)x._value;
  156. public static explicit operator string(B x) => (string)x._value;
  157. public static explicit operator Uri(B x) => (Uri)x._value;
  158. }
  159. }
  160.  
  161. namespace UnionLayout
  162. {
  163. public struct A
  164. {
  165. [StructLayout(LayoutKind.Explicit)]
  166. struct Union
  167. {
  168. [FieldOffset(0)]
  169. public int Int32;
  170. [FieldOffset(0)]
  171. public bool Bool;
  172. }
  173.  
  174. private object _obj;
  175. private Union _union;
  176. public AType Type { get; }
  177. private A(int x)
  178. {
  179. _obj = null;
  180. _union = default;
  181. _union.Int32 = x;
  182. Type = AType.Int32;
  183. }
  184. private A(string x)
  185. {
  186. _obj = x;
  187. _union = default;
  188. Type = AType.String;
  189. }
  190. private A(bool x)
  191. {
  192. _obj = null;
  193. _union = default;
  194. _union.Bool = x;
  195. Type = AType.Bool;
  196. }
  197.  
  198. public static A New(int x) => new A(x);
  199. public static A New(string x) => new A(x);
  200. public static A New(bool x) => new A(x);
  201.  
  202. public static explicit operator int(A x) => x._union.Int32;
  203. public static explicit operator string(A x) => (string)x._obj;
  204. public static explicit operator bool(A x) => x._union.Bool;
  205. }
  206.  
  207. public struct B
  208. {
  209. [StructLayout(LayoutKind.Explicit)]
  210. struct Union
  211. {
  212. [FieldOffset(0)]
  213. public int Int32;
  214. [FieldOffset(0)]
  215. public long Int64;
  216. [FieldOffset(0)]
  217. public DateTime DateTime;
  218. }
  219.  
  220. private object _obj;
  221. private Union _union;
  222. public BType Type { get; }
  223. private B(int x)
  224. {
  225. _obj = null;
  226. _union = default;
  227. _union.Int32 = x;
  228. Type = BType.Int32;
  229. }
  230. private B(long x)
  231. {
  232. _obj = null;
  233. _union = default;
  234. _union.Int64 = x;
  235. Type = BType.Int64;
  236. }
  237. private B(DateTime x)
  238. {
  239. _obj = null;
  240. _union = default;
  241. _union.DateTime = x;
  242. Type = BType.DateTime;
  243. }
  244. private B(string x)
  245. {
  246. _obj = x;
  247. _union = default;
  248. Type = BType.String;
  249. }
  250. private B(Uri x)
  251. {
  252. _obj = x;
  253. _union = default;
  254. Type = BType.Uri;
  255. }
  256.  
  257. public static B New(int x) => new B(x);
  258. public static B New(long x) => new B(x);
  259. public static B New(DateTime x) => new B(x);
  260. public static B New(string x) => new B(x);
  261. public static B New(Uri x) => new B(x);
  262.  
  263. public static explicit operator int(B x) => x._union.Int32;
  264. public static explicit operator long(B x) => x._union.Int64;
  265. public static explicit operator DateTime(B x) => x._union.DateTime;
  266. public static explicit operator string(B x) => (string)x._obj;
  267. public static explicit operator Uri(B x) => (Uri)x._obj;
  268. }
  269. }
  270.  
  271. namespace Bench
  272. {
  273. #if true
  274. using UnionLayout;
  275. /*
  276. Method | Mean | Error | StdDev |
  277. ------- |---------:|----------:|----------:|
  278. ForA | 48.47 us | 0.1606 us | 0.1502 us |
  279. ForB | 90.49 us | 0.5514 us | 0.4888 us |
  280. */
  281. #elif true
  282. using ObjectEnum;
  283. /*
  284. Method | Mean | Error | StdDev |
  285. ------- |---------:|----------:|----------:|
  286. ForA | 34.73 us | 0.1568 us | 0.1467 us |
  287. ForB | 75.75 us | 0.6201 us | 0.5800 us |
  288. */
  289. #elif true
  290. using ObjectOnly;
  291. /*
  292. Method | Mean | Error | StdDev |
  293. ------- |---------:|----------:|----------:|
  294. ForA | 35.08 us | 0.7959 us | 0.8846 us |
  295. ForB | 81.83 us | 0.2413 us | 0.2015 us |
  296. */
  297. #elif true
  298. using SubClass;
  299. /*
  300. Method | Mean | Error | StdDev |
  301. ------- |---------:|----------:|----------:|
  302. ForA | 35.50 us | 0.1092 us | 0.0968 us |
  303. ForB | 80.06 us | 0.4380 us | 0.3658 us |
  304. */
  305. #endif
  306.  
  307. public class Bench
  308. {
  309. private static readonly string[] Strings = new[]
  310. {
  311. "",
  312. "abc",
  313. "qawsertyuikolp",
  314. "あwせdrftgyふじこlp",
  315. "🐁🐂🐅🐇🐉🐍🐎🐑🐒🐓🐕🐗",
  316. "",
  317. "12345678901234567890",
  318. };
  319.  
  320. private static A NewA(Random r)
  321. {
  322. var v = r.Next(0, 3);
  323. switch (v)
  324. {
  325. default:
  326. case 0: return A.New(r.Next());
  327. case 1: return A.New(Strings[r.Next(0, Strings.Length)]);
  328. case 2: return A.New(r.Next(0, 1) != 0);
  329. }
  330. }
  331.  
  332. private static B NewB(Random r)
  333. {
  334. var v = r.Next(0, 5);
  335. switch (v)
  336. {
  337. default:
  338. case 0: return B.New(r.Next());
  339. case 1: return B.New((long)r.Next());
  340. case 2: return B.New(new DateTime((long)r.Next()));
  341. case 3: return B.New(Strings[r.Next(0, Strings.Length)]);
  342. case 4: return B.New(new Uri(Strings[r.Next(0, Strings.Length)], UriKind.Relative));
  343. }
  344. }
  345.  
  346. [Benchmark]
  347. public void ForA()
  348. {
  349. var r = new Random(0);
  350.  
  351. for (int i = 0; i < 1000; i++)
  352. {
  353. var a = NewA(r);
  354.  
  355. var sum = 0;
  356.  
  357. switch (a.Type)
  358. {
  359. case AType.Int32:
  360. sum += (int)a;
  361. break;
  362. case AType.String:
  363. sum += ((string)a).Length;
  364. break;
  365. case AType.Bool:
  366. sum += (bool)a ? 1 : -1;
  367. break;
  368. default:
  369. break;
  370. }
  371. }
  372. }
  373.  
  374. [Benchmark]
  375. public void ForB()
  376. {
  377. var r = new Random(0);
  378.  
  379. for (int i = 0; i < 1000; i++)
  380. {
  381. var a = NewB(r);
  382.  
  383. var sum = 0L;
  384.  
  385. switch (a.Type)
  386. {
  387. case BType.Int32:
  388. sum += (int)a;
  389. break;
  390. case BType.Int64:
  391. sum += (long)a;
  392. break;
  393. case BType.DateTime:
  394. sum += ((DateTime)a).Ticks;
  395. break;
  396. case BType.String:
  397. sum += ((string)a).Length;
  398. break;
  399. case BType.Uri:
  400. sum += ((Uri)a).OriginalString.Length;
  401. break;
  402. default:
  403. break;
  404. }
  405. }
  406. }
  407. }
  408. }
  409.  
  410. namespace ConsoleApp
  411. {
  412. class Program
  413. {
  414. static void Main()
  415. {
  416. #if false
  417. var x = new Bench.Bench();
  418. x.ForA();
  419. x.ForB();
  420. #else
  421. BenchmarkRunner.Run<Bench.Bench>();
  422. #endif
  423. }
  424. }
  425. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement