EndpointMetadataCollectionBenchmark.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright (c) .NET Foundation. All rights reserved.
  2. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  3. using System;
  4. using BenchmarkDotNet.Attributes;
  5. using Microsoft.AspNetCore.Http;
  6. namespace Microsoft.AspNetCore.Routing
  7. {
  8. public class EndpointMetadataCollectionBenchmark
  9. {
  10. private object[] _items;
  11. private EndpointMetadataCollection _collection;
  12. [Params(3, 10, 25)]
  13. public int Count { get; set; }
  14. [GlobalSetup]
  15. public void Setup()
  16. {
  17. var seeds = new Type[]
  18. {
  19. typeof(Metadata1),
  20. typeof(Metadata2),
  21. typeof(Metadata3),
  22. typeof(Metadata4),
  23. typeof(Metadata5),
  24. typeof(Metadata6),
  25. typeof(Metadata7),
  26. typeof(Metadata8),
  27. typeof(Metadata9),
  28. };
  29. _items = new object[Count];
  30. for (var i = 0; i < _items.Length; i++)
  31. {
  32. _items[i] = seeds[i % seeds.Length];
  33. }
  34. _collection = new EndpointMetadataCollection(_items);
  35. }
  36. // This is a synthetic baseline that visits each item and does an as-cast.
  37. [Benchmark(Baseline = true, OperationsPerInvoke = 5)]
  38. public void Baseline()
  39. {
  40. var items = _items;
  41. for (var i = items.Length - 1; i >= 0; i--)
  42. {
  43. GC.KeepAlive(_items[i] as IMetadata1);
  44. }
  45. for (var i = items.Length - 1; i >= 0; i--)
  46. {
  47. GC.KeepAlive(_items[i] as IMetadata2);
  48. }
  49. for (var i = items.Length - 1; i >= 0; i--)
  50. {
  51. GC.KeepAlive(_items[i] as IMetadata3);
  52. }
  53. for (var i = items.Length - 1; i >= 0; i--)
  54. {
  55. GC.KeepAlive(_items[i] as IMetadata4);
  56. }
  57. for (var i = items.Length - 1; i >= 0; i--)
  58. {
  59. GC.KeepAlive(_items[i] as IMetadata5);
  60. }
  61. }
  62. [Benchmark(OperationsPerInvoke = 5)]
  63. public void GetMetadata()
  64. {
  65. GC.KeepAlive(_collection.GetMetadata<IMetadata1>());
  66. GC.KeepAlive(_collection.GetMetadata<IMetadata2>());
  67. GC.KeepAlive(_collection.GetMetadata<IMetadata3>());
  68. GC.KeepAlive(_collection.GetMetadata<IMetadata4>());
  69. GC.KeepAlive(_collection.GetMetadata<IMetadata5>());
  70. }
  71. [Benchmark(OperationsPerInvoke = 5)]
  72. public void GetOrderedMetadata()
  73. {
  74. foreach (var item in _collection.GetOrderedMetadata<IMetadata1>())
  75. {
  76. GC.KeepAlive(item);
  77. }
  78. foreach (var item in _collection.GetOrderedMetadata<IMetadata2>())
  79. {
  80. GC.KeepAlive(item);
  81. }
  82. foreach (var item in _collection.GetOrderedMetadata<IMetadata3>())
  83. {
  84. GC.KeepAlive(item);
  85. }
  86. foreach (var item in _collection.GetOrderedMetadata<IMetadata4>())
  87. {
  88. GC.KeepAlive(item);
  89. }
  90. foreach (var item in _collection.GetOrderedMetadata<IMetadata5>())
  91. {
  92. GC.KeepAlive(item);
  93. }
  94. }
  95. private interface IMetadata1 { }
  96. private interface IMetadata2 { }
  97. private interface IMetadata3 { }
  98. private interface IMetadata4 { }
  99. private interface IMetadata5 { }
  100. private class Metadata1 : IMetadata1 { }
  101. private class Metadata2 : IMetadata2 { }
  102. private class Metadata3 : IMetadata3 { }
  103. private class Metadata4 : IMetadata4 { }
  104. private class Metadata5 : IMetadata5 { }
  105. private class Metadata6 : IMetadata1, IMetadata2 { }
  106. private class Metadata7 : IMetadata2, IMetadata3 { }
  107. private class Metadata8 : IMetadata4, IMetadata5 { }
  108. private class Metadata9 : IMetadata1, IMetadata2 { }
  109. }
  110. }