Skip to content

Adds Microsoft.Extensions.* performance tests with history #1362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Jun 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1690290
Reorganize source code
Oct 30, 2018
0194014
Merge branch 'release/2.1' into release/2.2
Oct 30, 2018
814a3b0
Merge branch 'release/2.2'
Oct 31, 2018
f240aca
Reorganize source code in preparation to move into aspnet/Extensions
Nov 2, 2018
5c3d7d7
Reorganize source code in preparation to move into aspnet/Extensions
Nov 2, 2018
4548ba5
Reorganize source code in preparation to move into aspnet/Extensions
Nov 2, 2018
4ee3c9e
Merge the source code from aspnet/DependencyInjection release/2.1
Nov 2, 2018
b7ccbb6
Merge branch 'release/2.1' into release/2.2
Nov 2, 2018
b52a855
Merge branch 'release/2.2'
Nov 2, 2018
2c88e33
Reorganize source code in preparation to move into aspnet/Extensions
Nov 7, 2018
d746978
Merge branch 'release/2.2'
Nov 7, 2018
893cb96
Reorganize source code in preparation to move into aspnet/Extensions
Nov 16, 2018
14a2e29
Use the SharedSourceRoot variable in project files
Nov 16, 2018
d58cbe8
Merge the source code from aspnet/HttpClientFactory into this repo
Nov 16, 2018
7bc945d
Merge branch 'release/2.1' into release/2.2
Nov 16, 2018
bfc6f92
Merge branch 'release/2.2'
Nov 16, 2018
0d0378b
Allow caching of IEnumerable services (dotnet/Extensions#575)
pakrym Nov 29, 2018
c7451bd
Reduce event source logger allocations (dotnet/Extensions#870)
pakrym Dec 27, 2018
89bed04
Use Arcade (dotnet/Extensions#586)
ryanbrandenburg Jan 29, 2019
242f3a1
Cleanup conversion to Arcade (dotnet/Extensions#1014)
natemcmaster Jan 30, 2019
dd2d8d7
Shrink StringValues (dotnet/Extensions#1283)
benaadams Mar 27, 2019
32e853b
Disable transitive project references in test projects (dotnet/Extens…
natemcmaster Jun 13, 2019
fc1df90
Fix HTTP client benchmarks
Jul 19, 2019
bdac559
Add typed client creation benchmark
Jul 19, 2019
0afd56b
Support netcoreapp3.1 TFM (dotnet/Extensions#2336)
Sep 13, 2019
c303731
Normalize all file headers to the expected Apache 2.0 license
sharwell Feb 26, 2020
8ffa5b7
Switch file headers to the MIT license
sharwell Feb 26, 2020
4622cb5
Merge branch 'master' of https://github.com/dotnet/performance into 4in1
maryamariyan Jun 17, 2020
48ba3c4
Moves Microsoft.Extensions.* perf tests over
maryamariyan Jun 17, 2020
fe1da91
Using the Open key to fully sign assembly
maryamariyan Jun 17, 2020
32a0653
Apply suggestions from code review
maryamariyan Jun 22, 2020
4caa9bd
Fix compile + other feedback
maryamariyan Jun 22, 2020
6f0a642
Apply suggestions from code review
adamsitnik Jun 23, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/benchmarks/micro/MicroBenchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<!-- Supported target frameworks -->
<TargetFrameworks Condition="'$(TargetFrameworks)' == '' AND '$(OS)' == 'Windows_NT'">net461;netcoreapp2.1;netcoreapp3.1;netcoreapp5.0</TargetFrameworks>
<TargetFrameworks Condition="'$(TargetFrameworks)' == ''">netcoreapp2.1;netcoreapp3.1;netcoreapp5.0</TargetFrameworks>

<NoWarn>$(NoWarn);CS8002</NoWarn>
<OutputType>Exe</OutputType>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>portable</DebugType>
Expand All @@ -21,6 +21,11 @@
<PackageReference Include="MessagePack" Version="1.9.11" />
<PackageReference Include="MessagePackAnalyzer" Version="1.7.3.7" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0-preview.4.20251.6" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.0-preview.4.20251.6" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0-preview.4.20251.6" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0-preview.4.20251.6" />
<PackageReference Include="Microsoft.Extensions.Logging.EventSource" Version="5.0.0-preview.4.20251.6" />
<PackageReference Include="Microsoft.Extensions.Primitives" Version="5.0.0-preview.4.20251.6" />
<PackageReference Include="protobuf-net" Version="2.4.0" />
<PackageReference Include="System.Drawing.Common" Version="4.5.1" />
<PackageReference Include="System.IO.Pipelines" Version="4.5.3" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using BenchmarkDotNet.Attributes;
using MicroBenchmarks;

namespace Microsoft.Extensions.DependencyInjection
{
[BenchmarkCategory(Categories.Libraries)]
public class ActivatorUtilitiesBenchmark
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: it would be great to remove Benchmark from the name but I don;t have any good ideas (ActivatorUtilitoes would confilict with the type of the same name..)

{
private ServiceProvider _serviceProvider;
private ObjectFactory _factory;
private object[] _factoryArguments;

[GlobalSetup]
public void SetUp()
{
var collection = new ServiceCollection();
collection.AddTransient<TypeToBeActivated>();
collection.AddSingleton<DependencyA>();
collection.AddSingleton<DependencyB>();
collection.AddSingleton<DependencyC>();
collection.AddTransient<TypeToBeActivated>();

_serviceProvider = collection.BuildServiceProvider();
_factory = ActivatorUtilities.CreateFactory(typeof(TypeToBeActivated), new Type[] { typeof(DependencyB), typeof(DependencyC) });
_factoryArguments = new object[] { new DependencyB(), new DependencyC() };
}

[Benchmark]
public TypeToBeActivated ServiceProvider() => _serviceProvider.GetService<TypeToBeActivated>();

[Benchmark]
public TypeToBeActivated Factory() => (TypeToBeActivated)_factory(_serviceProvider, _factoryArguments);

[Benchmark]
public TypeToBeActivated CreateInstance() => ActivatorUtilities.CreateInstance<TypeToBeActivated>(_serviceProvider, _factoryArguments);

public class TypeToBeActivated
{
public TypeToBeActivated(int i)
{
throw new NotImplementedException();
}

public TypeToBeActivated(string s)
{
throw new NotImplementedException();
}

public TypeToBeActivated(object o)
{
throw new NotImplementedException();
}

public TypeToBeActivated(DependencyA a, DependencyB b, DependencyC c)
{
}
}

public class DependencyA {}
public class DependencyB {}
public class DependencyC {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using MicroBenchmarks;

namespace Microsoft.Extensions.DependencyInjection
{
[BenchmarkCategory(Categories.Libraries)]
public class GetService : ServiceProviderEngineBenchmark
{
private IServiceProvider _transientSp;
private IServiceScope _scopedSp;
private IServiceProvider _singletonSp;
private IServiceProvider _serviceScopeFactoryProvider;
private IServiceProvider _serviceScope;
private IServiceProvider _emptyEnumerable;

[Benchmark(Baseline = true)]
public A NoDI() => new A(new B(new C()));

[GlobalSetup(Target = nameof(Transient))]
public void SetupTransient()
{
var services = new ServiceCollection();
services.AddTransient<A>();
services.AddTransient<B>();
services.AddTransient<C>();
_transientSp = services.BuildServiceProvider(new ServiceProviderOptions()
{
#if INTERNAL_DI
Mode = ServiceProviderMode
#endif
});
}

[Benchmark]
public A Transient() => _transientSp.GetService<A>();

[GlobalSetup(Target = nameof(Scoped))]
public void SetupScoped()
{
var services = new ServiceCollection();
services.AddScoped<A>();
services.AddScoped<B>();
services.AddScoped<C>();
_scopedSp = services.BuildServiceProvider(new ServiceProviderOptions()
{
#if INTERNAL_DI
Mode = ServiceProviderMode
#endif
}).CreateScope();
}

[Benchmark]
public A Scoped() => _scopedSp.ServiceProvider.GetService<A>();

[GlobalSetup(Target = nameof(Singleton))]
public void SetupScopedSingleton()
{
var services = new ServiceCollection();
services.AddSingleton<A>();
services.AddSingleton<B>();
services.AddSingleton<C>();
_singletonSp = services.BuildServiceProvider(new ServiceProviderOptions()
{
#if INTERNAL_DI
Mode = ServiceProviderMode
#endif
});
}

[Benchmark]
public A Singleton() => _singletonSp.GetService<A>();

[GlobalSetup(Target = nameof(ServiceScope))]
public void ServiceScopeSetup()
{
_serviceScope = new ServiceCollection().BuildServiceProvider(new ServiceProviderOptions()
{
#if INTERNAL_DI
Mode = ServiceProviderMode
#endif
});
}

[Benchmark]
public IServiceScope ServiceScope() => _serviceScope.CreateScope();

[GlobalSetup(Target = nameof(ServiceScopeProvider))]
public void ServiceScopeProviderSetup()
{
_serviceScopeFactoryProvider = new ServiceCollection().BuildServiceProvider(new ServiceProviderOptions()
{
#if INTERNAL_DI
Mode = ServiceProviderMode
#endif
});
}

[Benchmark]
public IServiceScopeFactory ServiceScopeProvider() => _serviceScopeFactoryProvider.GetService<IServiceScopeFactory>();

[GlobalSetup(Target = nameof(EmptyEnumerable))]
public void EmptyEnumerableSetup()
{
_emptyEnumerable = new ServiceCollection().BuildServiceProvider(new ServiceProviderOptions()
{
#if INTERNAL_DI
Mode = ServiceProviderMode
#endif
});
}

[Benchmark]
public object EmptyEnumerable() =>_emptyEnumerable.GetService<IEnumerable<A>>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using MicroBenchmarks;

namespace Microsoft.Extensions.DependencyInjection
{
[BenchmarkCategory(Categories.Libraries)]
public class GetServiceIEnumerable : ServiceProviderEngineBenchmark
{
private IServiceProvider _serviceProvider;

[GlobalSetup(Target = nameof(Transient))]
public void SetupTransient() => Setup(ServiceLifetime.Transient);

[GlobalSetup(Target = nameof(Scoped))]
public void SetupScoped() => Setup(ServiceLifetime.Scoped);

[GlobalSetup(Target = nameof(Singleton))]
public void SetupSingleton() => Setup(ServiceLifetime.Singleton);

private void Setup(ServiceLifetime lifetime)
{
IServiceCollection services = new ServiceCollection();
for (int i = 0; i < 10; i++)
{
services.Add(ServiceDescriptor.Describe(typeof(A), typeof(A), lifetime));
}

services.Add(ServiceDescriptor.Describe(typeof(B), typeof(B), lifetime));
services.Add(ServiceDescriptor.Describe(typeof(C), typeof(C), lifetime));

_serviceProvider = services.BuildServiceProvider(new ServiceProviderOptions()
{
#if INTERNAL_DI
Mode = ServiceProviderMode
#endif
}).CreateScope().ServiceProvider;
}

[Benchmark]
public object Transient() => _serviceProvider.GetService<IEnumerable<A>>();

[Benchmark]
public object Scoped() => _serviceProvider.GetService<IEnumerable<A>>();

[Benchmark]
public object Singleton() => _serviceProvider.GetService<IEnumerable<A>>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
using MicroBenchmarks;

namespace Microsoft.Extensions.DependencyInjection
{
[BenchmarkCategory(Categories.Libraries)]
public class ScopeValidation
{
private IServiceProvider _transientSp;
private IServiceProvider _transientSpScopeValidation;

[GlobalSetup]
public void Setup()
{
var services = new ServiceCollection();
services.AddTransient<A>();
services.AddTransient<B>();
services.AddTransient<C>();
_transientSp = services.BuildServiceProvider();

services = new ServiceCollection();
services.AddTransient<A>();
services.AddTransient<B>();
services.AddTransient<C>();
_transientSpScopeValidation = services.BuildServiceProvider(new ServiceProviderOptions { ValidateScopes = true });
}

[Benchmark(Baseline = true)]
public A Transient() => _transientSp.GetService<A>();

[Benchmark]
public A TransientWithScopeValidation() => _transientSpScopeValidation.GetService<A>();

public class A
{
public A(B b) { }
}

public class B
{
public B(C c) { }
}
public class C { }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
using MicroBenchmarks;

namespace Microsoft.Extensions.DependencyInjection
{
[BenchmarkCategory(Categories.Libraries)]
public class ServiceProviderEngineBenchmark
{
#if INTERNAL_DI
internal ServiceProviderMode ServiceProviderMode { get; private set; }

[Params("Expressions", "Dynamic", "Runtime", "ILEmit")]
public string Mode {
set {
ServiceProviderMode = (ServiceProviderMode)Enum.Parse(typeof(ServiceProviderMode), value);
}
}
#endif

public class A
{
public A(B b) { }
}

public class B
{
public B(C c) { }
}

public class C { }
}
}
Loading