StableCompositeDisposableBenchmark.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT License.
  3. // See the LICENSE file in the project root for more information.
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Reactive.Disposables;
  8. using System.Reactive.Linq;
  9. using System.Threading;
  10. using BenchmarkDotNet.Attributes;
  11. namespace Benchmarks.System.Reactive
  12. {
  13. [MemoryDiagnoser]
  14. public class StableCompositeDisposableBenchmark
  15. {
  16. [Params(3, 4, 5, 6, 7, 8, 9, 10, 100)]
  17. public int N;
  18. private IDisposable[] _array;
  19. private List<IDisposable> _list;
  20. [GlobalSetup]
  21. public void Setup()
  22. {
  23. _array = new IDisposable[N];
  24. for (var i = 0; i < N; i++)
  25. {
  26. _array[i] = Disposable.Empty;
  27. }
  28. _list = new List<IDisposable>(_array);
  29. }
  30. [Benchmark]
  31. public object Create_Array()
  32. {
  33. return StableCompositeDisposable.Create(_array);
  34. }
  35. [Benchmark]
  36. public object Create_Trusted_Array()
  37. {
  38. return CreateTrusted(_array);
  39. }
  40. [Benchmark]
  41. public object Create_List()
  42. {
  43. return StableCompositeDisposable.Create(_list);
  44. }
  45. [Benchmark]
  46. public object Dispose_Array()
  47. {
  48. var scd = StableCompositeDisposable.Create(_array);
  49. scd.Dispose();
  50. return scd;
  51. }
  52. [Benchmark]
  53. public object Dispose_List()
  54. {
  55. var scd = StableCompositeDisposable.Create(_list);
  56. scd.Dispose();
  57. return scd;
  58. }
  59. [Benchmark]
  60. public object Dispose_Trused_Array()
  61. {
  62. var scd = CreateTrusted(_array);
  63. scd.Dispose();
  64. return scd;
  65. }
  66. // The StableCompositeDisposable.CreateTrusted is inaccessible and
  67. // adding the InternalsVisibleTo attribute doesn't work (needs signed assemblies?)
  68. internal static ICancelable CreateTrusted(params IDisposable[] disposables)
  69. {
  70. return new NAryTrustedArray(disposables);
  71. }
  72. private sealed class NAryTrustedArray : StableCompositeDisposable
  73. {
  74. private IDisposable[] _disposables;
  75. public NAryTrustedArray(IDisposable[] disposables)
  76. {
  77. Volatile.Write(ref _disposables, disposables);
  78. }
  79. public override bool IsDisposed => Volatile.Read(ref _disposables) == null;
  80. public override void Dispose()
  81. {
  82. var old = Interlocked.Exchange(ref _disposables, null);
  83. if (old != null)
  84. {
  85. foreach (var d in old)
  86. {
  87. d.Dispose();
  88. }
  89. }
  90. }
  91. }
  92. }
  93. }