Guest User

Untitled

a guest
Nov 20th, 2017
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.58 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Runtime.Serialization;
  7. using System.Security.Cryptography;
  8. using System.Text;
  9. using Newtonsoft.Json;
  10.  
  11. namespace MessagePackVsProtobuf
  12. {
  13. [Serializable]
  14. [DataContract]
  15. public class Person
  16. {
  17. [DataMember(Order = 0)]
  18. public virtual int Age { get; set; }
  19.  
  20. [DataMember(Order = 1)]
  21. public virtual string FirstName { get; set; }
  22.  
  23. [DataMember(Order = 2)]
  24. public virtual string LastName { get; set; }
  25.  
  26. [DataMember(Order = 3)]
  27. public virtual Sex Sex { get; set; }
  28.  
  29. [DataMember(Order = 4)]
  30. public virtual IDictionary<string, string> Items { get; set; }
  31. }
  32.  
  33. public class Person2
  34. {
  35. public virtual int Age { get; set; }
  36.  
  37. public virtual string FirstName { get; set; }
  38.  
  39. public virtual string LastName { get; set; }
  40.  
  41. public virtual Sex Sex { get; set; }
  42.  
  43. public virtual IDictionary<string, string> Items { get; set; }
  44. }
  45.  
  46. public enum Sex
  47. {
  48. Unknown,
  49.  
  50. Male,
  51.  
  52. Female,
  53. }
  54.  
  55. public class Report
  56. {
  57. public string Name { get; set; }
  58.  
  59. public string TestType { get; set; }
  60.  
  61. public double SerializeTime { get; set; }
  62.  
  63. public double DeserializeTime { get; set; }
  64.  
  65. public double ReSerializeTime { get; set; }
  66.  
  67. public long Size { get; set; }
  68. }
  69.  
  70. internal class Program
  71. {
  72. private const int _iteration = 10000;
  73.  
  74. private const int _times = 3;
  75.  
  76. private static bool _dryRun = true;
  77.  
  78. private static List<Report> _reports = new List<Report>();
  79.  
  80. private const string _filename = "report.json";
  81.  
  82. private static void Main(string[] args)
  83. {
  84. var p = new Person
  85. {
  86. Age = 99,
  87. FirstName = NextString(6),
  88. LastName = NextString(6),
  89. Sex = Sex.Male,
  90. Items = new Dictionary<string, string> {{NextString(6), NextString(6)}}
  91. };
  92. IList<Person> l = Enumerable.Range(1, 1000)
  93. .Select(
  94. x => new Person
  95. {
  96. Age = x,
  97. FirstName = NextString(6),
  98. LastName = NextString(6),
  99. Sex = Sex.Female,
  100. Items = new Dictionary<string, string> {{NextString(6), NextString(6)}}
  101. })
  102. .ToArray();
  103.  
  104. #region protobuf-net single
  105.  
  106. {
  107. _dryRun = true;
  108. SerializeProtobuf(p, null);
  109. _dryRun = false;
  110. var reports = new List<Report>();
  111. for (int i = 0; i < _times; i++)
  112. {
  113. var report = new Report()
  114. {
  115. TestType = "Single Object",
  116. Name = "mgravell/protobuf-net",
  117. };
  118. var b = SerializeProtobuf(p, report);
  119. reports.Add(report);
  120. }
  121.  
  122. var averageReport = new Report
  123. {
  124. TestType = "Single Object",
  125. Name = "mgravell/protobuf-net",
  126. SerializeTime = reports.Average(report => report.SerializeTime),
  127. DeserializeTime = reports.Average(report => report.DeserializeTime),
  128. ReSerializeTime = reports.Average(report => report.ReSerializeTime),
  129. Size = reports.FirstOrDefault()?.Size ?? 0
  130. };
  131. _reports.Add(averageReport);
  132. }
  133.  
  134. #endregion
  135.  
  136. #region Official MsgPack-Cli single
  137.  
  138. {
  139. _dryRun = true;
  140. SerializeMsgPack(p, null);
  141. _dryRun = false;
  142. var reports = new List<Report>();
  143. for (int i = 0; i < _times; i++)
  144. {
  145. var report = new Report()
  146. {
  147. TestType = "Single Object",
  148. Name = "Official MsgPack-Cli",
  149. };
  150. var b = SerializeMsgPack(p, report);
  151. reports.Add(report);
  152. }
  153.  
  154. var averageReport = new Report
  155. {
  156. TestType = "Single Object",
  157. Name = "Official MsgPack-Cli",
  158. SerializeTime = reports.Average(report => report.SerializeTime),
  159. DeserializeTime = reports.Average(report => report.DeserializeTime),
  160. ReSerializeTime = reports.Average(report => report.ReSerializeTime),
  161. Size = reports.FirstOrDefault()?.Size ?? 0
  162. };
  163.  
  164. _reports.Add(averageReport);
  165. }
  166.  
  167. #endregion
  168.  
  169. #region neuecc/MessagePack-CSharp single
  170.  
  171. {
  172. _dryRun = true;
  173. SerializeMessagePack(p, null);
  174. _dryRun = false;
  175. var reports = new List<Report>();
  176. for (int i = 0; i < _times; i++)
  177. {
  178. var report = new Report()
  179. {
  180. TestType = "Single Object",
  181. Name = "neuecc/MessagePack-CSharp",
  182. };
  183. var b = SerializeMessagePack(p, report);
  184. reports.Add(report);
  185. }
  186.  
  187. var averageReport = new Report
  188. {
  189. TestType = "Single Object",
  190. Name = "neuecc/MessagePack-CSharp",
  191. SerializeTime = reports.Average(report => report.SerializeTime),
  192. DeserializeTime = reports.Average(report => report.DeserializeTime),
  193. ReSerializeTime = reports.Average(report => report.ReSerializeTime),
  194. Size = reports.FirstOrDefault()?.Size ?? 0
  195. };
  196.  
  197. _reports.Add(averageReport);
  198. }
  199.  
  200. #endregion
  201.  
  202. #region Newtonsoft.Json single
  203.  
  204. {
  205. _dryRun = true;
  206. SerializeNewtonsoftJson(p, null);
  207. _dryRun = false;
  208. var reports = new List<Report>();
  209. for (int i = 0; i < _times; i++)
  210. {
  211. var report = new Report()
  212. {
  213. TestType = "Single Object",
  214. Name = "Newtonsoft.Json",
  215. };
  216. var b = SerializeNewtonsoftJson(p, report);
  217. reports.Add(report);
  218. }
  219.  
  220. var averageReport = new Report
  221. {
  222. TestType = "Single Object",
  223. Name = "Newtonsoft.Json",
  224. SerializeTime = reports.Average(report => report.SerializeTime),
  225. DeserializeTime = reports.Average(report => report.DeserializeTime),
  226. ReSerializeTime = reports.Average(report => report.ReSerializeTime),
  227. Size = reports.FirstOrDefault()?.Size ?? 0
  228. };
  229.  
  230. _reports.Add(averageReport);
  231. }
  232.  
  233. #endregion
  234.  
  235. #region protobuf-net array
  236.  
  237. {
  238. _dryRun = true;
  239. SerializeProtobuf(l, null);
  240. _dryRun = false;
  241. var reports = new List<Report>();
  242. for (int i = 0; i < _times; i++)
  243. {
  244. var report = new Report()
  245. {
  246. TestType = "Large Array",
  247. Name = "mgravell/protobuf-net",
  248. };
  249. var b = SerializeProtobuf(l, report);
  250. reports.Add(report);
  251. }
  252.  
  253. var averageReport = new Report
  254. {
  255. TestType = "Large Array",
  256. Name = "mgravell/protobuf-net",
  257. SerializeTime = reports.Average(report => report.SerializeTime),
  258. DeserializeTime = reports.Average(report => report.DeserializeTime),
  259. ReSerializeTime = reports.Average(report => report.ReSerializeTime),
  260. Size = reports.FirstOrDefault()?.Size ?? 0
  261. };
  262.  
  263. _reports.Add(averageReport);
  264. }
  265.  
  266. #endregion
  267.  
  268. #region Official MsgPack-Cli array
  269.  
  270. {
  271. _dryRun = true;
  272. SerializeMsgPack(l, null);
  273. _dryRun = false;
  274. var reports = new List<Report>();
  275. for (int i = 0; i < _times; i++)
  276. {
  277. var report = new Report()
  278. {
  279. TestType = "Large Array",
  280. Name = "Official MsgPack-Cli",
  281. };
  282. var b = SerializeMsgPack(l, report);
  283. reports.Add(report);
  284. }
  285.  
  286. var averageReport = new Report
  287. {
  288. TestType = "Large Array",
  289. Name = "Official MsgPack-Cli",
  290. SerializeTime = reports.Average(report => report.SerializeTime),
  291. DeserializeTime = reports.Average(report => report.DeserializeTime),
  292. ReSerializeTime = reports.Average(report => report.ReSerializeTime),
  293. Size = reports.FirstOrDefault()?.Size ?? 0
  294. };
  295.  
  296. _reports.Add(averageReport);
  297. }
  298.  
  299. #endregion
  300.  
  301. #region neuecc/MessagePack-CSharp array
  302.  
  303. {
  304. _dryRun = true;
  305. SerializeMessagePack(l, null);
  306. _dryRun = false;
  307. var reports = new List<Report>();
  308. for (int i = 0; i < _times; i++)
  309. {
  310. var report = new Report()
  311. {
  312. TestType = "Large Array",
  313. Name = "neuecc/MessagePack-CSharp",
  314. };
  315. var b = SerializeMessagePack(l, report);
  316. reports.Add(report);
  317. }
  318.  
  319. var averageReport = new Report
  320. {
  321. TestType = "Large Array",
  322. Name = "neuecc/MessagePack-CSharp",
  323. SerializeTime = reports.Average(report => report.SerializeTime),
  324. DeserializeTime = reports.Average(report => report.DeserializeTime),
  325. ReSerializeTime = reports.Average(report => report.ReSerializeTime),
  326. Size = reports.FirstOrDefault()?.Size ?? 0
  327. };
  328.  
  329. _reports.Add(averageReport);
  330. }
  331.  
  332. #endregion
  333.  
  334. #region Newtonsoft.Json array
  335.  
  336. {
  337. _dryRun = true;
  338. SerializeNewtonsoftJson(l, null);
  339. _dryRun = false;
  340. var reports = new List<Report>();
  341. for (int i = 0; i < _times; i++)
  342. {
  343. var report = new Report()
  344. {
  345. TestType = "Large Array",
  346. Name = "Newtonsoft.Json",
  347. };
  348. var b = SerializeNewtonsoftJson(l, report);
  349. reports.Add(report);
  350. }
  351.  
  352. var averageReport = new Report
  353. {
  354. TestType = "Large Array",
  355. Name = "Newtonsoft.Json",
  356. SerializeTime = reports.Average(report => report.SerializeTime),
  357. DeserializeTime = reports.Average(report => report.DeserializeTime),
  358. ReSerializeTime = reports.Average(report => report.ReSerializeTime),
  359. Size = reports.FirstOrDefault()?.Size ?? 0
  360. };
  361.  
  362. _reports.Add(averageReport);
  363. }
  364.  
  365. #endregion
  366.  
  367. // Without Attribute
  368.  
  369. global::MessagePack.MessagePackSerializer.SetDefaultResolver(
  370. MessagePack.Resolvers.ContractlessStandardResolver.Instance);
  371.  
  372. var p2 = new Person2
  373. {
  374. Age = 99,
  375. FirstName = NextString(6),
  376. LastName = NextString(6),
  377. Sex = Sex.Male,
  378. Items = new Dictionary<string, string> {{NextString(6), NextString(6)}}
  379. };
  380. IList<Person2> l2 = Enumerable.Range(1, 1000)
  381. .Select(
  382. x => new Person2
  383. {
  384. Age = x,
  385. FirstName = NextString(6),
  386. LastName = NextString(6),
  387. Sex = Sex.Female,
  388. Items = new Dictionary<string, string>
  389. {
  390. {NextString(6), NextString(6)}
  391. }
  392. })
  393. .ToArray();
  394.  
  395. #region neuecc/MessagePack-CSharp single
  396.  
  397. {
  398. _dryRun = true;
  399. SerializeMessagePack(p2, null);
  400. _dryRun = false;
  401. var reports = new List<Report>();
  402. for (int i = 0; i < _times; i++)
  403. {
  404. var report = new Report()
  405. {
  406. TestType = "Single Object",
  407. Name = "neuecc/MessagePack-CSharp without Attribute",
  408. };
  409. var b = SerializeMessagePack(p2, report);
  410. reports.Add(report);
  411. }
  412.  
  413. var averageReport = new Report
  414. {
  415. TestType = "Single Object",
  416. Name = "neuecc/MessagePack-CSharp without Attribute",
  417. SerializeTime = reports.Average(report => report.SerializeTime),
  418. DeserializeTime = reports.Average(report => report.DeserializeTime),
  419. ReSerializeTime = reports.Average(report => report.ReSerializeTime),
  420. Size = reports.FirstOrDefault()?.Size ?? 0
  421. };
  422.  
  423. _reports.Add(averageReport);
  424. }
  425.  
  426. #endregion
  427.  
  428. #region neuecc/MessagePack-CSharp array
  429.  
  430. {
  431. _dryRun = true;
  432. SerializeMessagePack(l2, null);
  433. _dryRun = false;
  434. var reports = new List<Report>();
  435. for (int i = 0; i < _times; i++)
  436. {
  437. var report = new Report()
  438. {
  439. TestType = "Large Array",
  440. Name = "neuecc/MessagePack-CSharp without Attribute",
  441. };
  442. var b = SerializeMessagePack(l2, report);
  443. reports.Add(report);
  444. }
  445.  
  446. var averageReport = new Report
  447. {
  448. TestType = "Large Array",
  449. Name = "neuecc/MessagePack-CSharp without Attribute",
  450. SerializeTime = reports.Average(report => report.SerializeTime),
  451. DeserializeTime = reports.Average(report => report.DeserializeTime),
  452. ReSerializeTime = reports.Average(report => report.ReSerializeTime),
  453. Size = reports.FirstOrDefault()?.Size ?? 0
  454. };
  455.  
  456. _reports.Add(averageReport);
  457. }
  458.  
  459. #endregion
  460.  
  461. File.WriteAllText(_filename, JsonConvert.SerializeObject(_reports));
  462. Console.WriteLine("Test done");
  463. }
  464.  
  465. private static T SerializeProtobuf<T>(T original, Report report)
  466. {
  467. Console.WriteLine(report?.Name);
  468.  
  469. T copy = default(T);
  470. MemoryStream stream = null;
  471.  
  472. using (new Measure(Measure.MeasureType.Serialize, report))
  473. {
  474. for (int i = 0; i < _iteration; i++)
  475. {
  476. ProtoBuf.Serializer.Serialize<T>(stream = new MemoryStream(), original);
  477. }
  478. }
  479.  
  480. using (new Measure(Measure.MeasureType.Deserialize, report))
  481. {
  482. for (int i = 0; i < _iteration; i++)
  483. {
  484. stream.Position = 0;
  485. copy = ProtoBuf.Serializer.Deserialize<T>(stream);
  486. }
  487. }
  488.  
  489. using (new Measure(Measure.MeasureType.ReSerialize, report))
  490. {
  491. for (int i = 0; i < _iteration; i++)
  492. {
  493. ProtoBuf.Serializer.Serialize<T>(stream = new MemoryStream(), copy);
  494. }
  495. }
  496.  
  497. if (!_dryRun)
  498. {
  499. Console.WriteLine(string.Format("{0,15} {1}", "Size of Binary", ToHumanReadableSize(stream.Position)));
  500. report.Size = stream.Position;
  501. }
  502.  
  503. return copy;
  504. }
  505.  
  506. private static T SerializeMsgPack<T>(T original, Report report)
  507. {
  508. Console.WriteLine(report?.Name);
  509.  
  510. T copy = default(T);
  511.  
  512. MemoryStream stream = null;
  513. using (new Measure(Measure.MeasureType.Serialize, report))
  514. {
  515. for (int i = 0; i < _iteration; i++)
  516. {
  517. MsgPack.Serialization.MessagePackSerializer.Get<T>().Pack(stream = new MemoryStream(), original);
  518. }
  519. }
  520.  
  521. using (new Measure(Measure.MeasureType.Deserialize, report))
  522. {
  523. for (int i = 0; i < _iteration; i++)
  524. {
  525. stream.Position = 0;
  526. copy = MsgPack.Serialization.MessagePackSerializer.Get<T>().Unpack(stream);
  527. }
  528. }
  529.  
  530. using (new Measure(Measure.MeasureType.ReSerialize, report))
  531. {
  532. for (int i = 0; i < _iteration; i++)
  533. {
  534. MsgPack.Serialization.MessagePackSerializer.Get<T>().Pack(stream = new MemoryStream(), copy);
  535. }
  536. }
  537.  
  538. if (!_dryRun)
  539. {
  540. Console.WriteLine(string.Format("{0,15} {1}", "Size of Binary", ToHumanReadableSize(stream.Position)));
  541. report.Size = stream.Position;
  542. }
  543. return copy;
  544. }
  545.  
  546. private static T SerializeMessagePack<T>(T original, Report report)
  547. {
  548. Console.WriteLine(report?.Name);
  549.  
  550. T copy = default(T);
  551. MemoryStream stream = null;
  552.  
  553. using (new Measure(Measure.MeasureType.Serialize, report))
  554. {
  555. for (int i = 0; i < _iteration; i++)
  556. {
  557. global::MessagePack.MessagePackSerializer.Serialize(stream = new MemoryStream(), original);
  558. }
  559. }
  560.  
  561. using (new Measure(Measure.MeasureType.Deserialize, report))
  562. {
  563. for (int i = 0; i < _iteration; i++)
  564. {
  565. stream.Position = 0;
  566. copy = global::MessagePack.MessagePackSerializer.Deserialize<T>(stream);
  567. }
  568. }
  569.  
  570. using (new Measure(Measure.MeasureType.ReSerialize, report))
  571. {
  572. for (int i = 0; i < _iteration; i++)
  573. {
  574. global::MessagePack.MessagePackSerializer.Serialize(stream = new MemoryStream(), copy);
  575. }
  576. }
  577.  
  578. if (!_dryRun)
  579. {
  580. Console.WriteLine(string.Format("{0,15} {1}", "Size of Binary", ToHumanReadableSize(stream.Position)));
  581. report.Size = stream.Position;
  582. }
  583. return copy;
  584. }
  585.  
  586. private static T SerializeNewtonsoftJson<T>(T original, Report report)
  587. {
  588. Console.WriteLine(report?.Name);
  589.  
  590. var jsonSerializer = new JsonSerializer();
  591. T copy = default(T);
  592. MemoryStream stream = null;
  593.  
  594. using (new Measure(Measure.MeasureType.Serialize, report))
  595. {
  596. for (int i = 0; i < _iteration; i++)
  597. {
  598. stream = new MemoryStream();
  599. using (var tw = new StreamWriter(stream, Encoding.UTF8, 1024, true))
  600. using (var jw = new JsonTextWriter(tw))
  601. {
  602. jsonSerializer.Serialize(jw, original);
  603. }
  604. }
  605. }
  606.  
  607. using (new Measure(Measure.MeasureType.Deserialize, report))
  608. {
  609. for (int i = 0; i < _iteration; i++)
  610. {
  611. stream.Position = 0;
  612. using (var tr = new StreamReader(stream, Encoding.UTF8, false, 1024, true))
  613. using (var jr = new JsonTextReader(tr))
  614. {
  615. copy = jsonSerializer.Deserialize<T>(jr);
  616. }
  617. }
  618. }
  619.  
  620. using (new Measure(Measure.MeasureType.ReSerialize, report))
  621. {
  622. for (int i = 0; i < _iteration; i++)
  623. {
  624. stream = new MemoryStream();
  625. using (var tw = new StreamWriter(stream, Encoding.UTF8, 1024, true))
  626. using (var jw = new JsonTextWriter(tw))
  627. {
  628. jsonSerializer.Serialize(jw, copy);
  629. }
  630. }
  631. }
  632.  
  633. if (!_dryRun)
  634. {
  635. Console.WriteLine(string.Format("{0,15} {1}", "Size of Binary", ToHumanReadableSize(stream.Position)));
  636. report.Size = stream.Position;
  637. }
  638.  
  639. return copy;
  640. }
  641.  
  642. private struct Measure : IDisposable
  643. {
  644. public enum MeasureType
  645. {
  646. Serialize,
  647.  
  648. Deserialize,
  649.  
  650. ReSerialize
  651. }
  652.  
  653. private readonly MeasureType _measureType;
  654.  
  655. private readonly Report _report;
  656.  
  657. private readonly Stopwatch _stopwatch;
  658.  
  659. public Measure(MeasureType measureType, Report report)
  660. {
  661. _measureType = measureType;
  662. _report = report;
  663. _stopwatch = Stopwatch.StartNew();
  664. }
  665.  
  666. public void Dispose()
  667. {
  668. _stopwatch.Stop();
  669. if (!_dryRun)
  670. {
  671. Console.WriteLine($"{_measureType.ToString(),15} {_stopwatch.Elapsed.TotalMilliseconds} ms");
  672. switch (_measureType)
  673. {
  674. case MeasureType.Serialize:
  675. _report.SerializeTime = _stopwatch.Elapsed.TotalMilliseconds;
  676. break;
  677. case MeasureType.Deserialize:
  678. _report.DeserializeTime = _stopwatch.Elapsed.TotalMilliseconds;
  679. break;
  680. case MeasureType.ReSerialize:
  681. _report.ReSerializeTime = _stopwatch.Elapsed.TotalMilliseconds;
  682. break;
  683. default:
  684. throw new ArgumentOutOfRangeException();
  685. }
  686. }
  687.  
  688. GC.Collect();
  689. GC.WaitForPendingFinalizers();
  690. GC.Collect();
  691. }
  692. }
  693.  
  694. private static string ToHumanReadableSize(long size)
  695. {
  696. return ToHumanReadableSize(new Nullable<long>(size));
  697. }
  698.  
  699. private static string ToHumanReadableSize(long? size)
  700. {
  701. if (size == null)
  702. return "NULL";
  703.  
  704. double bytes = size.Value;
  705.  
  706. if (bytes <= 1024)
  707. return bytes.ToString("f2") + " B";
  708.  
  709. bytes = bytes / 1024;
  710. if (bytes <= 1024)
  711. return bytes.ToString("f2") + " KB";
  712.  
  713. bytes = bytes / 1024;
  714. if (bytes <= 1024)
  715. return bytes.ToString("f2") + " MB";
  716.  
  717. bytes = bytes / 1024;
  718. if (bytes <= 1024)
  719. return bytes.ToString("f2") + " GB";
  720.  
  721. bytes = bytes / 1024;
  722. if (bytes <= 1024)
  723. return bytes.ToString("f2") + " TB";
  724.  
  725. bytes = bytes / 1024;
  726. if (bytes <= 1024)
  727. return bytes.ToString("f2") + " PB";
  728.  
  729. bytes = bytes / 1024;
  730. if (bytes <= 1024)
  731. return bytes.ToString("f2") + " EB";
  732.  
  733. bytes = bytes / 1024;
  734. return bytes + " ZB";
  735. }
  736.  
  737. /// <summary>
  738. /// 生成随机字符串,字典为[A-Za-z0-9]
  739. /// </summary>
  740. /// <param name="length">字符串长度</param>
  741. /// <returns></returns>
  742. public static string NextString(int length)
  743. {
  744. const string dictionary = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  745. int dictCount = dictionary.Length;
  746. var builder = new StringBuilder(length);
  747. var bytes = new byte[length * 4];
  748. RandomNumberGenerator.Create().GetBytes(bytes);
  749. for (var i = 0; i < length; ++i)
  750. {
  751. builder.Append(dictionary[Math.Abs(BitConverter.ToInt32(bytes, i * 4)) % dictCount]);
  752. }
  753.  
  754. return builder.ToString();
  755. }
  756. }
  757. }
Add Comment
Please, Sign In to add comment