diff --git a/.gitignore b/.gitignore index ce725c264..8ff53697f 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ build/ bld/ [Bb]in/ [Oo]bj/ +BenchmarkDotNet.Artifacts/ # Visual Studio 2015 cache/options directory .vs/ diff --git a/Build.ps1 b/Build.ps1 index 721cb768d..9844f5bb7 100644 --- a/Build.ps1 +++ b/Build.ps1 @@ -18,4 +18,10 @@ Push-Location test/Serilog.Tests if($LASTEXITCODE -ne 0) { exit 2 } Pop-Location + +Push-Location test/Serilog.PerformanceTests + +& dotnet test -c Release +if($LASTEXITCODE -ne 0) { exit 2 } + Pop-Location diff --git a/build.sh b/build.sh index a76c0e90a..f1823c2a6 100755 --- a/build.sh +++ b/build.sh @@ -5,8 +5,14 @@ for path in src/*/project.json; do dotnet build ${dirname} -c Release done -for path in test/Serilog.Tests/project.json; do +# for path in test/Serilog.Tests/project.json; do + # dirname="$(dirname "${path}")" + # dotnet build ${dirname} -f netcoreapp1.0 -c Release + # dotnet test ${dirname} -f netcoreapp1.0 -c Release +# done + +for path in test/Serilog.PerformanceTests/project.json; do dirname="$(dirname "${path}")" dotnet build ${dirname} -f netcoreapp1.0 -c Release dotnet test ${dirname} -f netcoreapp1.0 -c Release -done +done \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/ForContext.cs b/test/Serilog.PerformanceTests/ForContext.cs new file mode 100644 index 000000000..9035e30a9 --- /dev/null +++ b/test/Serilog.PerformanceTests/ForContext.cs @@ -0,0 +1,70 @@ + +// Copyright 2013-2016 Serilog Contributors +// +// 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. + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Running; +using Serilog.Tests.Support; +using Serilog; +using System; +using Xunit; + +namespace Serilog.PerformanceTests +{ + /// + /// From https://github.com/serilog/serilog/pull/750 + /// + public class ForContext + { + private ILogger log; + + [Setup] + public void Setup() + { + log = new LoggerConfiguration() + .WriteTo.Sink(new DelegatingSink(e => { })) + .CreateLogger(); + } + + [Benchmark(Baseline = true)] + public void Baseline() + { + for (var i = 0; i < 10; ++i) + { + log.Information("Event!"); + } + } + + [Benchmark] + public void ForContextInfo10() + { + for (var i = 0; i < 10; ++i) + { + var ctx = log.ForContext("I", i); + ctx.Information("Event!"); + } + } + + [Benchmark] + public void ForContextInfo1000() + { + for (var i = 0; i < 1000; ++i) + { + var ctx = log.ForContext("I", i); + ctx.Information("Event!"); + } + } + } +} + \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/Harness.cs b/test/Serilog.PerformanceTests/Harness.cs new file mode 100644 index 000000000..206b88ae0 --- /dev/null +++ b/test/Serilog.PerformanceTests/Harness.cs @@ -0,0 +1,52 @@ + +// Copyright 2013-2016 Serilog Contributors +// +// 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. + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Running; +using Serilog.Tests.Support; +using Serilog; +using Serilog.Events; +using System; +using Xunit; + +namespace Serilog.PerformanceTests +{ + // TODO: + + // For Context + + // Perf logger off + // Perf level off - Debug - + + // LogContext Push + // ctor logevent - + // message template parser perf + // property binding perf (Bind message template) + + public class Runner + { + [Fact] + public void ForContext() + { + var context = BenchmarkRunner.Run(); + } + + [Fact] + public void MinimumLevel() + { + var context = BenchmarkRunner.Run(); + } + } +} \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/MinimumLevel.cs b/test/Serilog.PerformanceTests/MinimumLevel.cs new file mode 100644 index 000000000..e8bfad949 --- /dev/null +++ b/test/Serilog.PerformanceTests/MinimumLevel.cs @@ -0,0 +1,152 @@ + +// Copyright 2013-2016 Serilog Contributors +// +// 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. + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Running; +using Serilog; +using Serilog.Core; +using Serilog.Events; +using Serilog.Tests.Support; +using System; +using Xunit; + +namespace Serilog.PerformanceTests +{ + public class MinimumLevel + { + private ILogger log; + private LoggingLevelSwitch levelSwitch; + + [Setup] + public void Setup() + { + levelSwitch = new LoggingLevelSwitch(); + levelSwitch.MinimumLevel = LogEventLevel.Verbose; + + log = new LoggerConfiguration() + .MinimumLevel.ControlledBy(levelSwitch) + .WriteTo.Sink(new DelegatingSink(e => { })) + .CreateLogger(); + } + + [Benchmark(Baseline = true)] + public void Baseline() + { + //By default this is info, set to verbose for baseline + for (var i = 0; i < 1000; ++i) + { + log.Verbose("A verbose event!"); + log.Debug("A debug event!"); + log.Information("An info event!"); + log.Warning("A warm event!"); + log.Error("An error event!"); + log.Fatal("A fatal event!"); + } + } + + [Benchmark] + public void MinimumVerbose() + { + levelSwitch.MinimumLevel = LogEventLevel.Verbose; + + for (var i = 0; i < 1000; ++i) + { + log.Verbose("A verbose event!"); + log.Debug("A debug event!"); + log.Information("An info event!"); + log.Warning("A warm event!"); + log.Error("An error event!"); + log.Fatal("A fatal event!"); + } + } + + [Benchmark] + public void MinimumDebug() + { + levelSwitch.MinimumLevel = LogEventLevel.Debug; + + for (var i = 0; i < 1000; ++i) + { + log.Verbose("A verbose event!"); + log.Debug("A debug event!"); + log.Information("An info event!"); + log.Warning("A warm event!"); + log.Error("An error event!"); + log.Fatal("A fatal event!"); + } + } + + [Benchmark] + public void MinimumInfo() + { + levelSwitch.MinimumLevel = LogEventLevel.Information; + for (var i = 0; i < 1000; ++i) + { + log.Verbose("A verbose event!"); + log.Debug("A debug event!"); + log.Information("An info event!"); + log.Warning("A warm event!"); + log.Error("An error event!"); + log.Fatal("A fatal event!"); + } + } + + [Benchmark] + public void MinimumWarn() + { + levelSwitch.MinimumLevel = LogEventLevel.Warning; + for (var i = 0; i < 1000; ++i) + { + log.Verbose("A verbose event!"); + log.Debug("A debug event!"); + log.Information("An info event!"); + log.Warning("A warm event!"); + log.Error("An error event!"); + log.Fatal("A fatal event!"); + } + } + + [Benchmark] + public void MinimumError() + { + levelSwitch.MinimumLevel = LogEventLevel.Error; + for (var i = 0; i < 1000; ++i) + { + log.Verbose("A verbose event!"); + log.Debug("A debug event!"); + log.Information("An info event!"); + log.Warning("A warm event!"); + log.Error("An error event!"); + log.Fatal("A fatal event!"); + } + } + + [Benchmark] + public void MinimumFatal() + { + levelSwitch.MinimumLevel = LogEventLevel.Fatal; + for (var i = 0; i < 1000; ++i) + { + log.Verbose("A verbose event!"); + log.Debug("A debug event!"); + log.Information("An info event!"); + log.Warning("A warm event!"); + log.Error("An error event!"); + log.Fatal("A fatal event!"); + } + } + } +} + \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/Serilog.PerformanceTests.xproj b/test/Serilog.PerformanceTests/Serilog.PerformanceTests.xproj new file mode 100644 index 000000000..f4df042ba --- /dev/null +++ b/test/Serilog.PerformanceTests/Serilog.PerformanceTests.xproj @@ -0,0 +1,18 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + d7a37f73-bba3-4dae-9648-1a753a86f968 + Serilog.PerformanceTests + .\obj + .\bin\ + + + 2.0 + + + diff --git a/test/Serilog.PerformanceTests/project.json b/test/Serilog.PerformanceTests/project.json new file mode 100755 index 000000000..ec7536c64 --- /dev/null +++ b/test/Serilog.PerformanceTests/project.json @@ -0,0 +1,31 @@ +{ + "testRunner": "xunit", + + "dependencies": { + "Serilog": { "target": "project" }, + "Serilog.Tests": { "target": "project" }, + "TestDummies": { "target": "project" }, + "xunit": "2.1.0", + "dotnet-test-xunit": "1.0.0-rc2-build10015", + "BenchmarkDotNet": "0.9.7-beta" + }, + "buildOptions": { + "keyFile": "../../assets/Serilog.snk" + }, + "frameworks": { + "net4.5.2": { + }, + "netcoreapp1.0": { + "dependencies": { + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.0.0-rc2-3002702" + } + }, + "imports": [ + "dnxcore50", + "portable-net45+win8" + ] + } + } +}