diff --git a/src/benchmarks/Benchmarks.csproj b/src/benchmarks/Benchmarks.csproj
index 69158298199..370f0682281 100644
--- a/src/benchmarks/Benchmarks.csproj
+++ b/src/benchmarks/Benchmarks.csproj
@@ -6,7 +6,7 @@
pdbonly
true
true
- 7.3
+ latest
@@ -14,7 +14,7 @@
-
+
diff --git a/src/benchmarks/Categories.cs b/src/benchmarks/Categories.cs
index 61e8d802bd8..d7d2b66e33e 100644
--- a/src/benchmarks/Categories.cs
+++ b/src/benchmarks/Categories.cs
@@ -10,11 +10,15 @@ public static class Categories
public const string Inlining = "Inlining";
public const string V8 = "V8";
public const string Perflab = "Perflab";
+ public const string Virtual = "Virtual";
public const string CoreFX = "CoreFX";
public const string LINQ = "LINQ";
public const string SIMD = "SIMD";
public const string Span = "Span";
+ public const string Collections = "Collections";
+ public const string GenericCollections = "GenericCollections";
+ public const string NonGenericCollections = "NonGenericCollections";
}
}
\ No newline at end of file
diff --git a/src/benchmarks/Program.cs b/src/benchmarks/Program.cs
index 7a1f35e7791..1191eb45046 100644
--- a/src/benchmarks/Program.cs
+++ b/src/benchmarks/Program.cs
@@ -61,12 +61,8 @@ private static IConfig GetConfig(Options options)
config = config.With(new AllCategoriesFilter(options.AllCategories.ToArray()));
if (options.AnyCategories.Any())
config = config.With(new AnyCategoriesFilter(options.AnyCategories.ToArray()));
- if (options.Namespaces.Any())
- config = config.With(new NamespacesFilter(options.Namespaces.ToArray()));
- if (options.MethodNames.Any())
- config = config.With(new MethodNamesFilter(options.MethodNames.ToArray()));
- if (options.TypeNames.Any())
- config = config.With(new TypeNamesFilter(options.TypeNames.ToArray()));
+ if (options.Filters.Any())
+ config = config.With(new GlobFilter(options.Filters.ToArray()));
config = config.With(JsonExporter.Full); // make sure we export to Json (for BenchView integration purpose)
@@ -282,14 +278,8 @@ public class Options
[Option("anyCategories", Required = false, HelpText = "Any Categories to run")]
public IEnumerable AnyCategories { get; set; }
- [Option("namespace", Required = false, HelpText = "Namespace(s) to run")]
- public IEnumerable Namespaces { get; set; }
-
- [Option("method", Required = false, HelpText = "Method(s) to run")]
- public IEnumerable MethodNames { get; set; }
-
- [Option("class", Required = false, HelpText = "Class(es) with benchmarks to run")]
- public IEnumerable TypeNames { get; set; }
+ [Option('f', "filters", Required = false, HelpText = "Filter(s) to apply, globs that operate on namespace.typename.methodname")]
+ public IEnumerable Filters { get; set; }
[Option("join", Required = false, Default = false, HelpText = "Prints single table with results for all benchmarks")]
public bool Join { get; set; }
diff --git a/src/benchmarks/coreclr/Devirtualization/DefaultEqualityComparerPerf.cs b/src/benchmarks/coreclr/Devirtualization/DefaultEqualityComparerPerf.cs
index 3fdfcff1f34..77d59d6393d 100644
--- a/src/benchmarks/coreclr/Devirtualization/DefaultEqualityComparerPerf.cs
+++ b/src/benchmarks/coreclr/Devirtualization/DefaultEqualityComparerPerf.cs
@@ -57,7 +57,7 @@ public bool CompareWrapped(ref T x, ref T y)
}
}
- [BenchmarkCategory(Categories.CoreCLR)]
+ [BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)]
public class EqualityComparer
{
public enum E
diff --git a/src/benchmarks/corefx/Common/UniqueValuesGenerator.cs b/src/benchmarks/corefx/Common/UniqueValuesGenerator.cs
new file mode 100644
index 00000000000..fcf006a8a47
--- /dev/null
+++ b/src/benchmarks/corefx/Common/UniqueValuesGenerator.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Helpers
+{
+ internal static class UniqueValuesGenerator
+ {
+ private const int Seed = 12345; // we always use the same seed to have repeatable results!
+
+ internal static T[] GenerateArray(int count)
+ {
+ var random = new Random(Seed);
+
+ var uniqueValues = new HashSet();
+
+ while (uniqueValues.Count != count)
+ {
+ T value = GenerateValue(random);
+
+ if (!uniqueValues.Contains(value))
+ uniqueValues.Add(value);
+ }
+
+ return uniqueValues.ToArray();
+ }
+
+ internal static Dictionary GenerateDictionary(int count)
+ {
+ var random = new Random(Seed);
+
+ var dictionary = new Dictionary();
+
+ while (dictionary.Count != count)
+ {
+ TKey key = GenerateValue(random);
+
+ if (!dictionary.ContainsKey(key))
+ dictionary.Add(key, GenerateValue(random));
+ }
+
+ return dictionary;
+ }
+
+ private static T GenerateValue(Random random)
+ {
+ if (typeof(T) == typeof(int))
+ return (T)(object)random.Next();
+ if (typeof(T) == typeof(double))
+ return (T)(object)random.NextDouble();
+ if (typeof(T) == typeof(string))
+ return (T)(object)Guid.NewGuid().ToString(); // I am open to better ideas!
+
+ throw new NotImplementedException($"{typeof(T).Name} is not implemented");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Add/AddDefaultSize.cs b/src/benchmarks/corefx/System.Collections/Add/AddDefaultSize.cs
new file mode 100644
index 00000000000..d2768fe619f
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Add/AddDefaultSize.cs
@@ -0,0 +1,169 @@
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+using Helpers;
+
+namespace System.Collections
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int))] // value type
+ [GenericTypeArguments(typeof(string))] // reference type
+ public class AddDefaultSize
+ {
+ private T[] _uniqueValues;
+
+ [Params(Utils.DefaultCollectionSize)]
+ public int Count;
+
+ [GlobalSetup]
+ public void Setup() => _uniqueValues = UniqueValuesGenerator.GenerateArray(Count);
+
+ [Benchmark]
+ public List List()
+ {
+ var collection = new List();
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ [BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)]
+ public ICollection ICollection() => AddToICollection(new List());
+
+ [MethodImpl(MethodImplOptions.NoInlining)] // we want to prevent from inlining this particular method to make sure that JIT does not find out that ICollection is always List
+ private ICollection AddToICollection(ICollection collection)
+ {
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public HashSet HashSet()
+ {
+ var collection = new HashSet();
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public Dictionary Dictionary()
+ {
+ var collection = new Dictionary();
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i], uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ [BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)]
+ public IDictionary IDictionary() => AddToIDictionary(new Dictionary());
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private IDictionary AddToIDictionary(IDictionary collection)
+ {
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i], uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public SortedList SortedList()
+ {
+ var collection = new SortedList();
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i], uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public SortedSet SortedSet()
+ {
+ var collection = new SortedSet();
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public SortedDictionary SortedDictionary()
+ {
+ var collection = new SortedDictionary();
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i], uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public ConcurrentBag ConcurrentBag()
+ {
+ var collection = new ConcurrentBag();
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public Queue Queue()
+ {
+ var collection = new Queue();
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Enqueue(uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public Stack Stack()
+ {
+ var collection = new Stack();
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Push(uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public ConcurrentQueue ConcurrentQueue()
+ {
+ var collection = new ConcurrentQueue();
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Enqueue(uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public ConcurrentStack ConcurrentStack()
+ {
+ var collection = new ConcurrentStack();
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Push(uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public ConcurrentDictionary ConcurrentDictionary()
+ {
+ var collection = new ConcurrentDictionary();
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.TryAdd(uniqueValues[i], uniqueValues[i]);
+ return collection;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Add/AddGivenSize.cs b/src/benchmarks/corefx/System.Collections/Add/AddGivenSize.cs
new file mode 100644
index 00000000000..c9dad67f028
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Add/AddGivenSize.cs
@@ -0,0 +1,121 @@
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+using Helpers;
+
+namespace System.Collections
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int))] // value type
+ [GenericTypeArguments(typeof(string))] // reference type
+ public class AddGivenSize
+ {
+ private T[] _uniqueValues;
+
+ [Params(Utils.DefaultCollectionSize)]
+ public int Size;
+
+ [GlobalSetup]
+ public void Setup() => _uniqueValues = UniqueValuesGenerator.GenerateArray(Size);
+
+ [Benchmark]
+ public List List()
+ {
+ var collection = new List(Size);
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ [BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)]
+ public ICollection ICollection() => AddToICollection(new List(Size));
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private ICollection AddToICollection(ICollection collection)
+ {
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i]);
+ return collection;
+ }
+
+#if !NETFRAMEWORK // API added in .NET Core 2.0
+ [Benchmark]
+ public HashSet HashSet()
+ {
+ var collection = new HashSet(Size);
+ var uniqueValues = _uniqueValues;
+ for(int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i]);
+ return collection;
+ }
+#endif
+
+ [Benchmark]
+ public Dictionary Dictionary()
+ {
+ var collection = new Dictionary(Size);
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i], uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ [BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)]
+ public IDictionary IDictionary() => AddToIDictionary(new Dictionary(Size));
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private IDictionary AddToIDictionary(IDictionary collection)
+ {
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i], uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public SortedList SortedList()
+ {
+ var collection = new SortedList(Size);
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Add(uniqueValues[i], uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public Queue Queue()
+ {
+ var collection = new Queue(Size);
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Enqueue(uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public Stack Stack()
+ {
+ var collection = new Stack(Size);
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.Push(uniqueValues[i]);
+ return collection;
+ }
+
+ [Benchmark]
+ public ConcurrentDictionary ConcurrentDictionary()
+ {
+ var collection = new ConcurrentDictionary(Utils.ConcurrencyLevel, Size);
+ var uniqueValues = _uniqueValues;
+ for (int i = 0; i < uniqueValues.Length; i++)
+ collection.TryAdd(uniqueValues[i], uniqueValues[i]);
+ return collection;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Add/TryAddDefaultSize.cs b/src/benchmarks/corefx/System.Collections/Add/TryAddDefaultSize.cs
new file mode 100644
index 00000000000..5dafd160e6d
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Add/TryAddDefaultSize.cs
@@ -0,0 +1,44 @@
+using System.Collections.Generic;
+using System.Collections.Concurrent;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+using Helpers;
+
+namespace System.Collections
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int))] // value type
+ [GenericTypeArguments(typeof(string))] // reference type
+ public class TryAddDefaultSize
+ {
+ private T[] _uniqueValues;
+
+ [Params(Utils.DefaultCollectionSize)]
+ public int Count;
+
+ [GlobalSetup]
+ public void Setup() => _uniqueValues = UniqueValuesGenerator.GenerateArray(Count);
+
+#if !NETFRAMEWORK // API added in .NET Core 2.0
+ [Benchmark]
+ public Dictionary Dictionary()
+ {
+ var collection = new Dictionary();
+ var uniqueValues = _uniqueValues;
+ for(int i = 0; i < uniqueValues.Length; i++)
+ collection.TryAdd(uniqueValues[i], uniqueValues[i]);
+ return collection;
+ }
+#endif
+
+ [Benchmark]
+ public ConcurrentDictionary ConcurrentDictionary()
+ {
+ var collection = new ConcurrentDictionary();
+ var uniqueValues = _uniqueValues;
+ for(int i = 0; i < uniqueValues.Length; i++)
+ collection.TryAdd(uniqueValues[i], uniqueValues[i]);
+ return collection;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Add/TryAddGivenSize.cs b/src/benchmarks/corefx/System.Collections/Add/TryAddGivenSize.cs
new file mode 100644
index 00000000000..8ecdae098e0
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Add/TryAddGivenSize.cs
@@ -0,0 +1,44 @@
+using System.Collections.Generic;
+using System.Collections.Concurrent;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+using Helpers;
+
+namespace System.Collections
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int))] // value type
+ [GenericTypeArguments(typeof(string))] // reference type
+ public class TryAddGiventSize
+ {
+ private T[] _uniqueValues;
+
+ [Params(Utils.DefaultCollectionSize)]
+ public int Count;
+
+ [GlobalSetup]
+ public void Setup() => _uniqueValues = UniqueValuesGenerator.GenerateArray(Count);
+
+#if !NETFRAMEWORK // API added in .NET Core 2.0
+ [Benchmark]
+ public Dictionary Dictionary()
+ {
+ var collection = new Dictionary(Count);
+ var uniqueValues = _uniqueValues;
+ for(int i = 0; i < uniqueValues.Length; i++)
+ collection.TryAdd(uniqueValues[i], uniqueValues[i]);
+ return collection;
+ }
+#endif
+
+ [Benchmark]
+ public ConcurrentDictionary ConcurrentDictionary()
+ {
+ var collection = new ConcurrentDictionary(Utils.ConcurrencyLevel, Count);
+ var uniqueValues = _uniqueValues;
+ for(int i = 0; i < uniqueValues.Length; i++)
+ collection.TryAdd(uniqueValues[i], uniqueValues[i]);
+ return collection;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Concurrent/AddRemoveFromDifferentThreads.cs b/src/benchmarks/corefx/System.Collections/Concurrent/AddRemoveFromDifferentThreads.cs
new file mode 100644
index 00000000000..a670f8d653c
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Concurrent/AddRemoveFromDifferentThreads.cs
@@ -0,0 +1,151 @@
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+
+namespace System.Collections.Concurrent
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int))] // value type
+ [GenericTypeArguments(typeof(string))] // reference type
+ [MinWarmupCount(6, forceAutoWarmup: true)]
+ [MaxWarmupCount(10, forceAutoWarmup: true)]
+ public class AddRemoveFromDifferentThreads
+ {
+ const int NumThreads = 2;
+
+ [Params(2_000_000)]
+ public int Size;
+
+ private Barrier _barrier;
+ private Task _producer, _consumer;
+
+ [IterationCleanup]
+ public void IterationCleanup() => _barrier.Dispose();
+
+ [IterationSetup(Target = nameof(ConcurrentBag))]
+ public void SetupConcurrentBagIteration()
+ {
+ var bag = new ConcurrentBag();
+
+ _barrier = new Barrier(NumThreads + 1);
+
+ _producer = Task.Factory.StartNew(() =>
+ {
+ _barrier.SignalAndWait();
+ _barrier.SignalAndWait();
+
+ for (int i = 0; i < Size; i++)
+ {
+ bag.Add(default);
+ }
+ }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
+
+ _consumer = Task.Factory.StartNew(() =>
+ {
+ _barrier.SignalAndWait();
+ _barrier.SignalAndWait();
+
+ int count = 0;
+ while (count < Size)
+ {
+ if (bag.TryTake(out T _))
+ {
+ count++;
+ }
+ }
+ }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
+
+ _barrier.SignalAndWait();
+ }
+
+ [Benchmark]
+ public void ConcurrentBag() => SignalAndWaitForAllTasks();
+
+ [IterationSetup(Target = nameof(ConcurrentStack))]
+ public void SetupConcurrentStackIteration()
+ {
+ var stack = new ConcurrentStack();
+
+ _barrier = new Barrier(NumThreads + 1);
+
+ _producer = Task.Factory.StartNew(() =>
+ {
+ _barrier.SignalAndWait();
+ _barrier.SignalAndWait();
+
+ for (int i = 0; i < Size; i++)
+ {
+ stack.Push(default);
+ }
+ }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
+
+ _consumer = Task.Factory.StartNew(() =>
+ {
+ _barrier.SignalAndWait();
+ _barrier.SignalAndWait();
+
+ int count = 0;
+ while (count < Size)
+ {
+ if (stack.TryPop(out T _))
+ {
+ count++;
+ }
+ }
+ }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
+
+ _barrier.SignalAndWait();
+ }
+
+ [Benchmark]
+ public void ConcurrentStack() => SignalAndWaitForAllTasks();
+
+ [IterationSetup(Target = nameof(ConcurrentQueue))]
+ public void SetupConcurrentQueueIteration()
+ {
+ var queue = new ConcurrentQueue();
+
+ _barrier = new Barrier(NumThreads + 1);
+
+ _producer = Task.Factory.StartNew(() =>
+ {
+ _barrier.SignalAndWait();
+ _barrier.SignalAndWait();
+
+ for (int i = 0; i < Size; i++)
+ {
+ queue.Enqueue(default);
+ }
+ }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
+
+ _consumer = Task.Factory.StartNew(() =>
+ {
+ _barrier.SignalAndWait();
+ _barrier.SignalAndWait();
+
+ int count = 0;
+ while (count < Size)
+ {
+ if (queue.TryDequeue(out T _))
+ {
+ count++;
+ }
+ }
+ }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
+
+ _barrier.SignalAndWait();
+ }
+
+ [Benchmark]
+ public void ConcurrentQueue() => SignalAndWaitForAllTasks();
+
+ private void SignalAndWaitForAllTasks()
+ {
+ _barrier.SignalAndWait();
+
+ Task.WaitAll(_producer, _consumer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Concurrent/AddRemoveFromSameThreads.cs b/src/benchmarks/corefx/System.Collections/Concurrent/AddRemoveFromSameThreads.cs
new file mode 100644
index 00000000000..a01562ba48d
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Concurrent/AddRemoveFromSameThreads.cs
@@ -0,0 +1,106 @@
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+
+namespace System.Collections.Concurrent
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int))] // value type
+ [GenericTypeArguments(typeof(string))] // reference type
+ [MinWarmupCount(6, forceAutoWarmup: true)]
+ [MaxWarmupCount(10, forceAutoWarmup: true)]
+ public class AddRemoveFromSameThreads
+ {
+ const int NumThreads = 2;
+
+ [Params(2_000_000)]
+ public int Size;
+
+ private Barrier _barrier;
+ private Task[] _tasks;
+
+ [IterationCleanup]
+ public void IterationCleanup() => _barrier.Dispose();
+
+ [IterationSetup(Target = nameof(ConcurrentBag))]
+ public void SetupConcurrentBagIteration()
+ {
+ var bag = new ConcurrentBag();
+
+ _barrier = new Barrier(NumThreads + 1);
+ _tasks = Enumerable.Range(0, NumThreads)
+ .Select(_ =>
+ Task.Factory.StartNew(() =>
+ {
+ _barrier.SignalAndWait();
+
+ for (int i = 0; i < Size; i++)
+ {
+ bag.Add(default);
+ bag.TryTake(out T _);
+ }
+ }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default))
+ .ToArray();
+ }
+
+ [Benchmark]
+ public void ConcurrentBag() => SignalAndWaitForAllTasks();
+
+ [IterationSetup(Target = nameof(ConcurrentStack))]
+ public void SetupConcurrentStackIteration()
+ {
+ var stack = new ConcurrentStack();
+
+ _barrier = new Barrier(NumThreads + 1);
+ _tasks = Enumerable.Range(0, NumThreads)
+ .Select(_ =>
+ Task.Factory.StartNew(() =>
+ {
+ _barrier.SignalAndWait();
+
+ for (int i = 0; i < Size; i++)
+ {
+ stack.Push(default);
+ stack.TryPop(out T _);
+ }
+ }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default))
+ .ToArray();
+ }
+
+ [Benchmark]
+ public void ConcurrentStack() => SignalAndWaitForAllTasks();
+
+ [IterationSetup(Target = nameof(ConcurrentQueue))]
+ public void SetupConcurrentQueueIteration()
+ {
+ var queue = new ConcurrentQueue();
+
+ _barrier = new Barrier(NumThreads + 1);
+ _tasks = Enumerable.Range(0, NumThreads)
+ .Select(_ =>
+ Task.Factory.StartNew(() =>
+ {
+ _barrier.SignalAndWait();
+
+ for (int i = 0; i < Size; i++)
+ {
+ queue.Enqueue(default);
+ queue.TryDequeue(out T _);
+ }
+ }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default))
+ .ToArray();
+ }
+
+ [Benchmark]
+ public void ConcurrentQueue() => SignalAndWaitForAllTasks();
+
+ private void SignalAndWaitForAllTasks()
+ {
+ _barrier.SignalAndWait();
+
+ Task.WaitAll(_tasks);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Concurrent/Count.cs b/src/benchmarks/corefx/System.Collections/Concurrent/Count.cs
new file mode 100644
index 00000000000..e45c9ca3a61
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Concurrent/Count.cs
@@ -0,0 +1,44 @@
+using System.Linq;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+using Helpers;
+
+namespace System.Collections.Concurrent
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int))] // value type
+ [GenericTypeArguments(typeof(string))] // reference type
+ public class Count
+ {
+ private ConcurrentDictionary _dictionary;
+ private ConcurrentQueue _queue;
+ private ConcurrentStack _stack;
+ private ConcurrentBag _bag;
+
+ [Params(Utils.DefaultCollectionSize)]
+ public int Size;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ var values = UniqueValuesGenerator.GenerateArray(Size);
+
+ _dictionary = new ConcurrentDictionary(values.ToDictionary(v => v, v => v));
+ _queue = new ConcurrentQueue(values);
+ _stack = new ConcurrentStack(values);
+ _bag = new ConcurrentBag(values);
+ }
+
+ [Benchmark]
+ public int Dictionary() => _dictionary.Count;
+
+ [Benchmark]
+ public int Queue() => _queue.Count;
+
+ [Benchmark]
+ public int Stack() => _stack.Count;
+
+ [Benchmark]
+ public int Bag() => _bag.Count;
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Concurrent/IsEmpty.cs b/src/benchmarks/corefx/System.Collections/Concurrent/IsEmpty.cs
new file mode 100644
index 00000000000..dc202819fe1
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Concurrent/IsEmpty.cs
@@ -0,0 +1,44 @@
+using System.Linq;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+using Helpers;
+
+namespace System.Collections.Concurrent
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int))] // value type
+ [GenericTypeArguments(typeof(string))] // reference type
+ public class IsEmpty
+ {
+ private ConcurrentDictionary _dictionary;
+ private ConcurrentQueue _queue;
+ private ConcurrentStack _stack;
+ private ConcurrentBag _bag;
+
+ [Params(Utils.DefaultCollectionSize)]
+ public int Size;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ var values = UniqueValuesGenerator.GenerateArray(Size);
+
+ _dictionary = new ConcurrentDictionary(values.ToDictionary(v => v, v => v));
+ _queue = new ConcurrentQueue(values);
+ _stack = new ConcurrentStack(values);
+ _bag = new ConcurrentBag(values);
+ }
+
+ [Benchmark]
+ public bool Dictionary() => _dictionary.IsEmpty;
+
+ [Benchmark]
+ public bool Queue() => _queue.IsEmpty;
+
+ [Benchmark]
+ public bool Stack() => _stack.IsEmpty;
+
+ [Benchmark]
+ public bool Bag() => _bag.IsEmpty;
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Contains/ContainsFalse.cs b/src/benchmarks/corefx/System.Collections/Contains/ContainsFalse.cs
new file mode 100644
index 00000000000..7e78798d9a1
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Contains/ContainsFalse.cs
@@ -0,0 +1,188 @@
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+using Helpers;
+
+namespace System.Collections
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int))] // value type
+ [GenericTypeArguments(typeof(string))] // reference type
+ public class ContainsFalse
+ {
+ private T[] _notFound;
+
+ private T[] _array;
+ private List _list;
+ private LinkedList _linkedList;
+ private HashSet _hashSet;
+ private Queue _queue;
+ private Stack _stack;
+ private SortedSet _sortedSet;
+ private ImmutableArray _immutableArray;
+ private ImmutableHashSet _immutableHashSet;
+ private ImmutableList _immutableList;
+ private ImmutableSortedSet _immutableSortedSet;
+
+ [Params(Utils.DefaultCollectionSize)]
+ public int Size;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ var values = UniqueValuesGenerator.GenerateArray(Size * 2);
+ _notFound = values.Take(Size).ToArray();
+ var secondHalf = values.Skip(Size).Take(Size).ToArray();
+
+ _array = secondHalf;
+ _list = new List(secondHalf);
+ _linkedList = new LinkedList(secondHalf);
+ _hashSet = new HashSet(secondHalf);
+ _queue = new Queue(secondHalf);
+ _stack = new Stack(secondHalf);
+ _sortedSet = new SortedSet(secondHalf);
+ _immutableArray = Immutable.ImmutableArray.CreateRange(secondHalf);
+ _immutableHashSet = Immutable.ImmutableHashSet.CreateRange(secondHalf);
+ _immutableList = Immutable.ImmutableList.CreateRange(secondHalf);
+ _immutableSortedSet = Immutable.ImmutableSortedSet.CreateRange(secondHalf);
+ }
+
+ [Benchmark]
+ public bool Array()
+ {
+ bool result = default;
+ var collection = _array;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.Contains(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool List()
+ {
+ bool result = default;
+ var collection = _list;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.Contains(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ [BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)]
+ public bool ICollection() => Contains(_list);
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private bool Contains(ICollection collection)
+ {
+ bool result = default;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.Contains(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool LinkedList()
+ {
+ bool result = default;
+ var collection = _linkedList;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.Contains(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool HashSet()
+ {
+ bool result = default;
+ var collection = _hashSet;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.Contains(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool Queue()
+ {
+ bool result = default;
+ var collection = _queue;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.Contains(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool Stack()
+ {
+ bool result = default;
+ var collection = _stack;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.Contains(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool SortedSet()
+ {
+ bool result = default;
+ var collection = _sortedSet;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.Contains(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ImmutableArray()
+ {
+ bool result = default;
+ var collection = _immutableArray;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.Contains(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ImmutableHashSet()
+ {
+ bool result = default;
+ var collection = _immutableHashSet;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.Contains(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ImmutableList()
+ {
+ bool result = default;
+ var collection = _immutableList;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.Contains(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ImmutableSortedSet()
+ {
+ bool result = default;
+ var collection = _immutableSortedSet;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.Contains(notFound[i]);
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Contains/ContainsKeyFalse.cs b/src/benchmarks/corefx/System.Collections/Contains/ContainsKeyFalse.cs
new file mode 100644
index 00000000000..c7bff8d14e9
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Contains/ContainsKeyFalse.cs
@@ -0,0 +1,125 @@
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+using Helpers;
+
+namespace System.Collections
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int), typeof(int))] // value type
+ [GenericTypeArguments(typeof(string), typeof(string))] // reference type
+ public class ContainsKeyFalse
+ {
+ private TKey[] _notFound;
+ private Dictionary _source;
+
+ private Dictionary _dictionary;
+ private SortedList _sortedList;
+ private SortedDictionary _sortedDictionary;
+ private ConcurrentDictionary _concurrentDictionary;
+ private ImmutableDictionary _immutableDictionary;
+ private ImmutableSortedDictionary _immutableSortedDictionary;
+
+ [Params(Utils.DefaultCollectionSize)]
+ public int Size;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ var values = UniqueValuesGenerator.GenerateArray(Size * 2);
+ _notFound = values.Take(Size).ToArray();
+
+ _source = values.Skip(Size).Take(Size).ToDictionary(item => item, item => (TValue)(object)item);
+ _dictionary = new Dictionary(_source);
+ _sortedList = new SortedList(_source);
+ _sortedDictionary = new SortedDictionary(_source);
+ _concurrentDictionary = new ConcurrentDictionary(_source);
+ _immutableDictionary = Immutable.ImmutableDictionary.CreateRange(_source);
+ _immutableSortedDictionary = Immutable.ImmutableSortedDictionary.CreateRange(_source);
+ }
+
+ [Benchmark]
+ public bool Dictionary()
+ {
+ bool result = default;
+ var collection = _dictionary;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.ContainsKey(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ [BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)]
+ public bool IDictionary() => ContainsKey(_dictionary);
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public bool ContainsKey(IDictionary collection)
+ {
+ bool result = default;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.ContainsKey(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool SortedList()
+ {
+ bool result = default;
+ var collection = _sortedList;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.ContainsKey(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool SortedDictionary()
+ {
+ bool result = default;
+ var collection = _sortedDictionary;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.ContainsKey(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ConcurrentDictionary()
+ {
+ bool result = default;
+ var collection = _concurrentDictionary;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.ContainsKey(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ImmutableDictionary()
+ {
+ bool result = default;
+ var collection = _immutableDictionary;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.ContainsKey(notFound[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ImmutableSortedDictionary()
+ {
+ bool result = default;
+ var collection = _immutableSortedDictionary;
+ var notFound = _notFound;
+ for (int i = 0; i < notFound.Length; i++)
+ result ^= collection.ContainsKey(notFound[i]);
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Contains/ContainsKeyTrue.cs b/src/benchmarks/corefx/System.Collections/Contains/ContainsKeyTrue.cs
new file mode 100644
index 00000000000..6f580767c00
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Contains/ContainsKeyTrue.cs
@@ -0,0 +1,123 @@
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+using Helpers;
+
+namespace System.Collections
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int), typeof(int))] // value type
+ [GenericTypeArguments(typeof(string), typeof(string))] // reference type
+ public class ContainsKeyTrue
+ {
+ private TKey[] _found;
+ private Dictionary _source;
+
+ private Dictionary _dictionary;
+ private SortedList _sortedList;
+ private SortedDictionary _sortedDictionary;
+ private ConcurrentDictionary _concurrentDictionary;
+ private ImmutableDictionary _immutableDictionary;
+ private ImmutableSortedDictionary _immutableSortedDictionary;
+
+ [Params(Utils.DefaultCollectionSize)]
+ public int Size;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _found = UniqueValuesGenerator.GenerateArray(Size);
+ _source = _found.ToDictionary(item => item, item => (TValue)(object)item);
+ _dictionary = new Dictionary(_source);
+ _sortedList = new SortedList(_source);
+ _sortedDictionary = new SortedDictionary(_source);
+ _concurrentDictionary = new ConcurrentDictionary(_source);
+ _immutableDictionary = Immutable.ImmutableDictionary.CreateRange(_source);
+ _immutableSortedDictionary = Immutable.ImmutableSortedDictionary.CreateRange(_source);
+ }
+
+ [Benchmark]
+ public bool Dictionary()
+ {
+ bool result = default;
+ var collection = _dictionary;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.ContainsKey(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ [BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)]
+ public bool IDictionary() => ContainsKey(_dictionary);
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public bool ContainsKey(IDictionary collection)
+ {
+ bool result = default;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.ContainsKey(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool SortedList()
+ {
+ bool result = default;
+ var collection = _sortedList;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.ContainsKey(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool SortedDictionary()
+ {
+ bool result = default;
+ var collection = _sortedDictionary;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.ContainsKey(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ConcurrentDictionary()
+ {
+ bool result = default;
+ var collection = _concurrentDictionary;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.ContainsKey(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ImmutableDictionary()
+ {
+ bool result = default;
+ var collection = _immutableDictionary;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.ContainsKey(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ImmutableSortedDictionary()
+ {
+ bool result = default;
+ var collection = _immutableSortedDictionary;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.ContainsKey(found[i]);
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Contains/ContainsTrue.cs b/src/benchmarks/corefx/System.Collections/Contains/ContainsTrue.cs
new file mode 100644
index 00000000000..53bd8dd1f21
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Contains/ContainsTrue.cs
@@ -0,0 +1,185 @@
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+using Helpers;
+
+namespace System.Collections
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int))] // value type
+ [GenericTypeArguments(typeof(string))] // reference type
+ public class ContainsTrue
+ {
+ private T[] _found;
+
+ private T[] _array;
+ private List _list;
+ private LinkedList _linkedList;
+ private HashSet _hashSet;
+ private Queue _queue;
+ private Stack _stack;
+ private SortedSet _sortedSet;
+ private ImmutableArray _immutableArray;
+ private ImmutableHashSet _immutableHashSet;
+ private ImmutableList _immutableList;
+ private ImmutableSortedSet _immutableSortedSet;
+
+ [Params(Utils.DefaultCollectionSize)]
+ public int Size;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _found = UniqueValuesGenerator.GenerateArray(Size);
+ _array = _found.ToArray();
+ _list = new List(_found);
+ _linkedList = new LinkedList(_found);
+ _hashSet = new HashSet(_found);
+ _queue = new Queue(_found);
+ _stack = new Stack(_found);
+ _sortedSet = new SortedSet(_found);
+ _immutableArray = Immutable.ImmutableArray.CreateRange(_found);
+ _immutableHashSet = Immutable.ImmutableHashSet.CreateRange(_found);
+ _immutableList = Immutable.ImmutableList.CreateRange(_found);
+ _immutableSortedSet = Immutable.ImmutableSortedSet.CreateRange(_found);
+ }
+
+ [Benchmark]
+ public bool Array()
+ {
+ bool result = default;
+ var collection = _array;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.Contains(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool List()
+ {
+ bool result = default;
+ var collection = _list;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.Contains(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ [BenchmarkCategory(Categories.CoreCLR, Categories.Virtual)]
+ public bool ICollection() => Contains(_list);
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private bool Contains(ICollection collection)
+ {
+ bool result = default;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.Contains(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool LinkedList()
+ {
+ bool result = default;
+ var collection = _linkedList;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.Contains(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool HashSet()
+ {
+ bool result = default;
+ var collection = _hashSet;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.Contains(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool Queue()
+ {
+ bool result = default;
+ var collection = _queue;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.Contains(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool Stack()
+ {
+ bool result = default;
+ var collection = _stack;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.Contains(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool SortedSet()
+ {
+ bool result = default;
+ var collection = _sortedSet;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.Contains(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ImmutableArray()
+ {
+ bool result = default;
+ var collection = _immutableArray;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.Contains(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ImmutableHashSet()
+ {
+ bool result = default;
+ var collection = _immutableHashSet;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.Contains(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ImmutableList()
+ {
+ bool result = default;
+ var collection = _immutableList;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.Contains(found[i]);
+ return result;
+ }
+
+ [Benchmark]
+ public bool ImmutableSortedSet()
+ {
+ bool result = default;
+ var collection = _immutableSortedSet;
+ var found = _found;
+ for (int i = 0; i < found.Length; i++)
+ result ^= collection.Contains(found[i]);
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Create/CtorDefaultSize.cs b/src/benchmarks/corefx/System.Collections/Create/CtorDefaultSize.cs
new file mode 100644
index 00000000000..f5b60870a8c
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Create/CtorDefaultSize.cs
@@ -0,0 +1,77 @@
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+
+namespace System.Collections
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int))] // value type
+ [GenericTypeArguments(typeof(string))] // reference type
+ public class CtorDefaultSize
+ {
+ [Benchmark]
+ public List List() => new List();
+
+ [Benchmark]
+ public LinkedList LinkedList() => new LinkedList();
+
+ [Benchmark]
+ public HashSet HashSet() => new HashSet();
+
+ [Benchmark]
+ public Dictionary Dictionary() => new Dictionary();
+
+ [Benchmark]
+ public Queue Queue() => new Queue();
+
+ [Benchmark]
+ public Stack Stack() => new Stack();
+
+ [Benchmark]
+ public SortedList SortedList() => new SortedList();
+
+ [Benchmark]
+ public SortedSet SortedSet() => new SortedSet();
+
+ [Benchmark]
+ public SortedDictionary SortedDictionary() => new SortedDictionary();
+
+ [Benchmark]
+ public ConcurrentDictionary ConcurrentDictionary() => new ConcurrentDictionary();
+
+ [Benchmark]
+ public ConcurrentQueue ConcurrentQueue() => new ConcurrentQueue();
+
+ [Benchmark]
+ public ConcurrentStack ConcurrentStack() => new ConcurrentStack();
+
+ [Benchmark]
+ public ConcurrentBag ConcurrentBag() => new ConcurrentBag();
+
+ [Benchmark]
+ public ImmutableArray ImmutableArray() => Immutable.ImmutableArray.Create();
+
+ [Benchmark]
+ public ImmutableDictionary ImmutableDictionary() => Immutable.ImmutableDictionary.Create();
+
+ [Benchmark]
+ public ImmutableHashSet ImmutableHashSet() => Immutable.ImmutableHashSet.Create();
+
+ [Benchmark]
+ public ImmutableList ImmutableList() => Immutable.ImmutableList.Create();
+
+ [Benchmark]
+ public ImmutableQueue ImmutableQueue() => Immutable.ImmutableQueue.Create();
+
+ [Benchmark]
+ public ImmutableStack ImmutableStack() => Immutable.ImmutableStack.Create();
+
+ [Benchmark]
+ public ImmutableSortedDictionary ImmutableSortedDictionary() => Immutable.ImmutableSortedDictionary.Create();
+
+ [Benchmark]
+ public ImmutableSortedSet ImmutableSortedSet() => Immutable.ImmutableSortedSet.Create();
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Create/CtorDefaultSizeNonGeneric.cs b/src/benchmarks/corefx/System.Collections/Create/CtorDefaultSizeNonGeneric.cs
new file mode 100644
index 00000000000..2d01d66c25e
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Create/CtorDefaultSizeNonGeneric.cs
@@ -0,0 +1,24 @@
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+
+namespace System.Collections
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.NonGenericCollections)]
+ public class CtorDefaultSizeNonGeneric
+ {
+ [Benchmark]
+ public ArrayList ArrayList() => new ArrayList();
+
+ [Benchmark]
+ public Hashtable Hashtable() => new Hashtable();
+
+ [Benchmark]
+ public Queue Queue() => new Queue();
+
+ [Benchmark]
+ public Stack Stack() => new Stack();
+
+ [Benchmark]
+ public SortedList SortedList() => new SortedList();
+ }
+}
\ No newline at end of file
diff --git a/src/benchmarks/corefx/System.Collections/Create/CtorFromCollection.cs b/src/benchmarks/corefx/System.Collections/Create/CtorFromCollection.cs
new file mode 100644
index 00000000000..ffd56570ccd
--- /dev/null
+++ b/src/benchmarks/corefx/System.Collections/Create/CtorFromCollection.cs
@@ -0,0 +1,91 @@
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+using Helpers;
+
+namespace System.Collections
+{
+ [BenchmarkCategory(Categories.CoreFX, Categories.Collections, Categories.GenericCollections)]
+ [GenericTypeArguments(typeof(int))] // value type
+ [GenericTypeArguments(typeof(string))] // reference type
+ public class CtorFromCollection
+ {
+ private ICollection _collection;
+ private IDictionary _dictionary;
+
+ [Params(Utils.DefaultCollectionSize)]
+ public int Size;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _collection = UniqueValuesGenerator.GenerateArray(Size);
+ _dictionary = UniqueValuesGenerator.GenerateDictionary(Size);
+ }
+
+ [Benchmark]
+ public List List() => new List(_collection);
+
+ [Benchmark]
+ public LinkedList LinkedList() => new LinkedList(_collection);
+
+ [Benchmark]
+ public HashSet HashSet() => new HashSet(_collection);
+
+ [Benchmark]
+ public Dictionary Dictionary() => new Dictionary(_dictionary);
+
+ [Benchmark]
+ public Queue Queue() => new Queue(_collection);
+
+ [Benchmark]
+ public Stack Stack() => new Stack(_collection);
+
+ [Benchmark]
+ public SortedList SortedList() => new SortedList(_dictionary);
+
+ [Benchmark]
+ public SortedSet SortedSet() => new SortedSet