diff --git a/.gitignore b/.gitignore
index 13cc9c6b..78ce6dd1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -86,3 +86,5 @@ PrecompiledWeb
/examples/Spring/Spring.Mvc4QuickStart/packages
project.lock.json
+
+BenchmarkDotNet.Artifacts
diff --git a/Spring.Net.sln b/Spring.Net.sln
index 2be5bc59..a938b9ab 100644
--- a/Spring.Net.sln
+++ b/Spring.Net.sln
@@ -9,9 +9,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
changelog.txt = changelog.txt
common-project.include = common-project.include
Local.testsettings = Local.testsettings
- readme.txt = readme.txt
Spring.build = Spring.build
Spring.include = Spring.include
+ README.md = README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{79F495DF-83D6-435E-A20E-47800F6F8FE7}"
@@ -95,6 +95,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Data.NHibernate5.Nes
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Data.NHibernate5.Tests", "test\Spring\Spring.Data.NHibernate5.Tests\Spring.Data.NHibernate5.Tests.csproj", "{BEEBC49B-4519-4C77-AE93-11E68F4CA7E3}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Benchmark", "test\Spring\Spring.Benchmark\Spring.Benchmark.csproj", "{504F1D7B-C6AC-4128-9411-D680B3086662}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{9537C677-ADE5-4503-AFD7-3E0C3B0960EB}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|.NET = Debug|.NET
@@ -511,6 +515,18 @@ Global
{BEEBC49B-4519-4C77-AE93-11E68F4CA7E3}.Release|Any CPU.Build.0 = Release|Any CPU
{BEEBC49B-4519-4C77-AE93-11E68F4CA7E3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{BEEBC49B-4519-4C77-AE93-11E68F4CA7E3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {504F1D7B-C6AC-4128-9411-D680B3086662}.Debug|.NET.ActiveCfg = Debug|Any CPU
+ {504F1D7B-C6AC-4128-9411-D680B3086662}.Debug|.NET.Build.0 = Debug|Any CPU
+ {504F1D7B-C6AC-4128-9411-D680B3086662}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {504F1D7B-C6AC-4128-9411-D680B3086662}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {504F1D7B-C6AC-4128-9411-D680B3086662}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {504F1D7B-C6AC-4128-9411-D680B3086662}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {504F1D7B-C6AC-4128-9411-D680B3086662}.Release|.NET.ActiveCfg = Release|Any CPU
+ {504F1D7B-C6AC-4128-9411-D680B3086662}.Release|.NET.Build.0 = Release|Any CPU
+ {504F1D7B-C6AC-4128-9411-D680B3086662}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {504F1D7B-C6AC-4128-9411-D680B3086662}.Release|Any CPU.Build.0 = Release|Any CPU
+ {504F1D7B-C6AC-4128-9411-D680B3086662}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {504F1D7B-C6AC-4128-9411-D680B3086662}.Release|Mixed Platforms.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -522,4 +538,7 @@ Global
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = Spring.Net.vsmdi
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {504F1D7B-C6AC-4128-9411-D680B3086662} = {9537C677-ADE5-4503-AFD7-3E0C3B0960EB}
+ EndGlobalSection
EndGlobal
diff --git a/Spring.Net.sln.DotSettings b/Spring.Net.sln.DotSettings
index 191cf932..375aca96 100644
--- a/Spring.Net.sln.DotSettings
+++ b/Spring.Net.sln.DotSettings
@@ -65,4 +65,5 @@
1
True
True
+ True
True
\ No newline at end of file
diff --git a/test/Spring/Spring.Benchmark/App.config b/test/Spring/Spring.Benchmark/App.config
new file mode 100644
index 00000000..402699ae
--- /dev/null
+++ b/test/Spring/Spring.Benchmark/App.config
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Spring/Spring.Benchmark/Classes/Singleton.cs b/test/Spring/Spring.Benchmark/Classes/Singleton.cs
new file mode 100644
index 00000000..54f099f5
--- /dev/null
+++ b/test/Spring/Spring.Benchmark/Classes/Singleton.cs
@@ -0,0 +1,82 @@
+using System;
+
+namespace Spring.Benchmark.Classes
+{
+ public interface ISingleton1
+ {
+ void DoSomething();
+ }
+
+ public interface ISingleton2
+ {
+ void DoSomething();
+ }
+
+ public interface ISingleton3
+ {
+ void DoSomething();
+ }
+
+ public class Singleton1 : ISingleton1
+ {
+ private static int counter;
+
+ public Singleton1()
+ {
+ System.Threading.Interlocked.Increment(ref counter);
+ }
+
+ public static int Instances
+ {
+ get { return counter; }
+ set { counter = value; }
+ }
+
+ public void DoSomething()
+ {
+ Console.WriteLine("Hello");
+ }
+ }
+
+ public class Singleton2 : ISingleton2
+ {
+ private static int counter;
+
+ public Singleton2()
+ {
+ System.Threading.Interlocked.Increment(ref counter);
+ }
+
+ public static int Instances
+ {
+ get { return counter; }
+ set { counter = value; }
+ }
+
+ public void DoSomething()
+ {
+ Console.WriteLine("Hello");
+ }
+ }
+
+ public class Singleton3 : ISingleton3
+ {
+ private static int counter;
+
+ public Singleton3()
+ {
+ System.Threading.Interlocked.Increment(ref counter);
+ }
+
+ public static int Instances
+ {
+ get { return counter; }
+ set { counter = value; }
+ }
+
+ public void DoSomething()
+ {
+ Console.WriteLine("Hello");
+ }
+ }
+}
diff --git a/test/Spring/Spring.Benchmark/Classes/Transient.cs b/test/Spring/Spring.Benchmark/Classes/Transient.cs
new file mode 100644
index 00000000..4526d879
--- /dev/null
+++ b/test/Spring/Spring.Benchmark/Classes/Transient.cs
@@ -0,0 +1,82 @@
+using System;
+
+namespace Spring.Benchmark.Classes
+{
+ public interface ITransient1
+ {
+ void DoSomething();
+ }
+
+ public interface ITransient2
+ {
+ void DoSomething();
+ }
+
+ public interface ITransient3
+ {
+ void DoSomething();
+ }
+
+ public class Transient1 : ITransient1
+ {
+ private static int counter;
+
+ public Transient1()
+ {
+ System.Threading.Interlocked.Increment(ref counter);
+ }
+
+ public static int Instances
+ {
+ get { return counter; }
+ set { counter = value; }
+ }
+
+ public void DoSomething()
+ {
+ Console.WriteLine("World");
+ }
+ }
+
+ public class Transient2 : ITransient2
+ {
+ private static int counter;
+
+ public Transient2()
+ {
+ System.Threading.Interlocked.Increment(ref counter);
+ }
+
+ public static int Instances
+ {
+ get { return counter; }
+ set { counter = value; }
+ }
+
+ public void DoSomething()
+ {
+ Console.WriteLine("World");
+ }
+ }
+
+ public class Transient3 : ITransient3
+ {
+ private static int counter;
+
+ public Transient3()
+ {
+ System.Threading.Interlocked.Increment(ref counter);
+ }
+
+ public static int Instances
+ {
+ get { return counter; }
+ set { counter = value; }
+ }
+
+ public void DoSomething()
+ {
+ Console.WriteLine("World");
+ }
+ }
+}
diff --git a/test/Spring/Spring.Benchmark/ContainerBenchmark.cs b/test/Spring/Spring.Benchmark/ContainerBenchmark.cs
new file mode 100644
index 00000000..ea432603
--- /dev/null
+++ b/test/Spring/Spring.Benchmark/ContainerBenchmark.cs
@@ -0,0 +1,73 @@
+#region License
+
+// /*
+// * Copyright 2018 the original author or authors.
+// *
+// * Licensed under the Apache License, Version 2.0 (the "License");
+// * you may not use this file except in compliance with the License.
+// * You may obtain a copy of the License at
+// *
+// * http://www.apache.org/licenses/LICENSE-2.0
+// *
+// * Unless required by applicable law or agreed to in writing, software
+// * distributed under the License is distributed on an "AS IS" BASIS,
+// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// * See the License for the specific language governing permissions and
+// * limitations under the License.
+// */
+
+#endregion
+
+using BenchmarkDotNet.Attributes;
+using Spring.Benchmark.Classes;
+using Spring.Context;
+using Spring.Context.Support;
+
+namespace Spring.Benchmark
+{
+ [MediumRunJob]
+ [MemoryDiagnoser]
+ public class ContainerBenchmark
+ {
+ private IApplicationContext container;
+
+ [Params(5_000)]
+ public int Iterations { get; set; }
+
+ [GlobalSetup]
+ public void GlobalSetup()
+ {
+ container = ContextRegistry.GetContext();
+ }
+
+ [Benchmark]
+ public bool ResolveTransient()
+ {
+ bool ok = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ var transient1 = (ITransient1) container.GetObject(typeof(ITransient1).FullName);
+ var transient2 = (ITransient2) container.GetObject(typeof(ITransient2).FullName);
+ var transient3 = (ITransient3) container.GetObject(typeof(ITransient3).FullName);
+ ok &= transient1 != null && transient2 != null && transient3 != null;
+ }
+
+ return ok;
+ }
+
+ [Benchmark]
+ public bool ResolveSingleton()
+ {
+ bool ok = true;
+ for (int i = 0; i < Iterations; i++)
+ {
+ var transient1 = (ISingleton1) container.GetObject(typeof(ISingleton1).FullName);
+ var transient2 = (ISingleton2) container.GetObject(typeof(ISingleton2).FullName);
+ var transient3 = (ISingleton3) container.GetObject(typeof(ISingleton3).FullName);
+ ok &= transient1 != null && transient2 != null && transient3 != null;
+ }
+
+ return ok;
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Spring/Spring.Benchmark/HybridSetBenchmark.cs b/test/Spring/Spring.Benchmark/HybridSetBenchmark.cs
new file mode 100644
index 00000000..b101d49f
--- /dev/null
+++ b/test/Spring/Spring.Benchmark/HybridSetBenchmark.cs
@@ -0,0 +1,86 @@
+#region License
+// /*
+// * Copyright 2018 the original author or authors.
+// *
+// * Licensed under the Apache License, Version 2.0 (the "License");
+// * you may not use this file except in compliance with the License.
+// * You may obtain a copy of the License at
+// *
+// * http://www.apache.org/licenses/LICENSE-2.0
+// *
+// * Unless required by applicable law or agreed to in writing, software
+// * distributed under the License is distributed on an "AS IS" BASIS,
+// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// * See the License for the specific language governing permissions and
+// * limitations under the License.
+// */
+#endregion
+
+using System.Collections.Generic;
+using BenchmarkDotNet.Attributes;
+using Spring.Collections;
+using Spring.Objects.Factory.Support;
+
+namespace Spring.Benchmark
+{
+ [MediumRunJob]
+ [MemoryDiagnoser]
+ public class HybridSetBenchmark
+ {
+ private HashedSet hashedSet;
+ private HashSet hashSet;
+ private HybridSet hybridSet;
+ private MethodOverrides[] items;
+
+ [GlobalSetup]
+ public void GlobalSetup()
+ {
+ items = new MethodOverrides[100];
+ for (int i = 0; i < items.Length; i++)
+ {
+ items[i] = new MethodOverrides();
+ }
+ }
+
+ [IterationSetup]
+ public void Setup()
+ {
+ hashSet = new HashSet();
+ hybridSet = new HybridSet();
+ hashedSet = new HashedSet();
+ }
+
+ [Params(1, 5, 10, 20)]
+ public int Iterations { get; set; }
+
+ [Benchmark]
+ public void AddHashSet()
+ {
+ int iterations = Iterations;
+ for (int i = 0; i < iterations; ++i)
+ {
+ hashSet.Add(items[i]);
+ }
+ }
+
+ [Benchmark]
+ public void AddHashedSet()
+ {
+ int iterations = Iterations;
+ for (int i = 0; i < iterations; ++i)
+ {
+ hashedSet.Add(items[i]);
+ }
+ }
+
+ [Benchmark]
+ public void AddHybridSet()
+ {
+ int iterations = Iterations;
+ for (int i = 0; i < iterations; ++i)
+ {
+ hybridSet.Add(items[i]);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Spring/Spring.Benchmark/Program.cs b/test/Spring/Spring.Benchmark/Program.cs
new file mode 100644
index 00000000..892eb9cf
--- /dev/null
+++ b/test/Spring/Spring.Benchmark/Program.cs
@@ -0,0 +1,12 @@
+using BenchmarkDotNet.Running;
+
+namespace Spring.Benchmark
+{
+ public static class Program
+ {
+ public static void Main(string[] args)
+ {
+ BenchmarkSwitcher.FromAssembly(typeof(HybridSetBenchmark).Assembly).Run(args);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Spring/Spring.Benchmark/Spring.Benchmark.csproj b/test/Spring/Spring.Benchmark/Spring.Benchmark.csproj
new file mode 100644
index 00000000..38dc4add
--- /dev/null
+++ b/test/Spring/Spring.Benchmark/Spring.Benchmark.csproj
@@ -0,0 +1,17 @@
+
+
+
+ Exe
+ netcoreapp2.1
+ Spring.Benchmark
+
+
+
+
+
+
+
+
+
+
+