From bc445014fae8d4a93db5800a80a32bc00ea86859 Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Fri, 19 Aug 2016 17:11:13 +1000 Subject: [PATCH] Updated (micro) benchmarks --- RunPerfTests.ps1 | 21 +-- Serilog.sln | 5 +- .../ForContextTests.cs | 80 --------- .../FromLogContextPushPropertyTests.cs | 99 ------------ test/Serilog.PerformanceTests/Harness.cs | 39 ++--- .../LevelControlBenchmark.cs | 66 ++++++++ .../LogContextEnrichmentBenchmark.cs | 63 ++++++++ .../Serilog.PerformanceTests/LogEventTests.cs | 72 --------- .../MessageTemplateParsingBenchmark.cs | 41 +++++ .../MinimumLevelTests.cs | 152 ------------------ .../NestedLoggerCreationBenchmark.cs | 33 ++++ .../NestedLoggerLatencyBenchmark.cs | 42 +++++ ...ateParserTests.cs => PipelineBenchmark.cs} | 33 ++-- .../Support/NullSink.cs | 12 ++ test/Serilog.PerformanceTests/Support/Some.cs | 20 +++ test/Serilog.PerformanceTests/project.json | 4 +- 16 files changed, 325 insertions(+), 457 deletions(-) delete mode 100644 test/Serilog.PerformanceTests/ForContextTests.cs delete mode 100644 test/Serilog.PerformanceTests/FromLogContextPushPropertyTests.cs create mode 100644 test/Serilog.PerformanceTests/LevelControlBenchmark.cs create mode 100644 test/Serilog.PerformanceTests/LogContextEnrichmentBenchmark.cs delete mode 100644 test/Serilog.PerformanceTests/LogEventTests.cs create mode 100644 test/Serilog.PerformanceTests/MessageTemplateParsingBenchmark.cs delete mode 100644 test/Serilog.PerformanceTests/MinimumLevelTests.cs create mode 100644 test/Serilog.PerformanceTests/NestedLoggerCreationBenchmark.cs create mode 100644 test/Serilog.PerformanceTests/NestedLoggerLatencyBenchmark.cs rename test/Serilog.PerformanceTests/{MessageTemplateParserTests.cs => PipelineBenchmark.cs} (60%) create mode 100644 test/Serilog.PerformanceTests/Support/NullSink.cs create mode 100644 test/Serilog.PerformanceTests/Support/Some.cs diff --git a/RunPerfTests.ps1 b/RunPerfTests.ps1 index 8e83073ce..bc6cda3df 100644 --- a/RunPerfTests.ps1 +++ b/RunPerfTests.ps1 @@ -1,21 +1,16 @@ Push-Location $PSScriptRoot -if(Test-Path .\artifacts) { Remove-Item .\artifacts -Force -Recurse } +./Build.ps1 -& dotnet restore +foreach ($test in ls test/*.PerformanceTests) { + Push-Location $test -$revision = @{ $true = $env:APPVEYOR_BUILD_NUMBER; $false = 1 }[$env:APPVEYOR_BUILD_NUMBER -ne $NULL]; + echo "perf: Running performance test project in $test" -Push-Location src/Serilog + & dotnet test -c Release + if($LASTEXITCODE -ne 0) { exit 2 } -& dotnet build -c Release -o ..\..\.\artifacts --version-suffix=$revision -if($LASTEXITCODE -ne 0) { exit 1 } - -Pop-Location -Push-Location test/Serilog.PerformanceTests - -& dotnet test -c Release -if($LASTEXITCODE -ne 0) { exit 2 } + Pop-Location +} Pop-Location -Pop-Location diff --git a/Serilog.sln b/Serilog.sln index d8a0c1773..32d2b0d9b 100644 --- a/Serilog.sln +++ b/Serilog.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{037440DE-440B-4129-9F7A-09B42D00397E}" EndProject @@ -12,10 +12,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "assets", "assets", "{E9D1B5 .editorconfig = .editorconfig appveyor.yml = appveyor.yml Build.ps1 = Build.ps1 + build.sh = build.sh CHANGES.md = CHANGES.md global.json = global.json NuGet.config = NuGet.config README.md = README.md + run_perf_tests.sh = run_perf_tests.sh + RunPerfTests.ps1 = RunPerfTests.ps1 assets\Serilog.snk = assets\Serilog.snk EndProjectSection EndProject diff --git a/test/Serilog.PerformanceTests/ForContextTests.cs b/test/Serilog.PerformanceTests/ForContextTests.cs deleted file mode 100644 index cb07318c5..000000000 --- a/test/Serilog.PerformanceTests/ForContextTests.cs +++ /dev/null @@ -1,80 +0,0 @@ - -// 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 ForContextTests - { - 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!"); - } - } - - [Benchmark] - public void ForContextInfo10000() - { - for (var i = 0; i < 10000; ++i) - { - var ctx = log.ForContext("I", i); - ctx.Information("Event!"); - } - } - } -} - \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/FromLogContextPushPropertyTests.cs b/test/Serilog.PerformanceTests/FromLogContextPushPropertyTests.cs deleted file mode 100644 index 8008829e4..000000000 --- a/test/Serilog.PerformanceTests/FromLogContextPushPropertyTests.cs +++ /dev/null @@ -1,99 +0,0 @@ - -// 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.Context; -using System; -using Xunit; - -namespace Serilog.PerformanceTests -{ - public class FromLogContextPushPropertyTests - { - ILogger log; - - [Setup] - public void Setup() - { - log = new LoggerConfiguration() - .WriteTo.Sink(new DelegatingSink(e => { })) - .Enrich.FromLogContext() - .CreateLogger(); - } - - [Benchmark(Baseline = true)] - public void Baseline() - { - for (var i = 0; i < 1000; ++i) - { - log.Information("Event!"); - } - } - - [Benchmark] - public void Push1Property1000() - { - for (var i = 0; i < 1000; ++i) - { - using (LogContext.PushProperty("A", 2)) - { - log.Information("Event!"); - } - } - } - - [Benchmark] - public void Push1Property10000() - { - for (var i = 0; i < 10000; ++i) - { - using (LogContext.PushProperty("A", 2)) - { - log.Information("Event!"); - } - } - } - - [Benchmark] - public void Push2Properties1000() - { - for (var i = 0; i < 1000; ++i) - { - using (LogContext.PushProperty("A", 2)) - using (LogContext.PushProperty("B", 1)) - { - log.Information("Event!"); - } - } - } - - [Benchmark] - public void Push2Properties10000() - { - for (var i = 0; i < 10000; ++i) - { - using (LogContext.PushProperty("A", 2)) - using (LogContext.PushProperty("B", 1)) - { - log.Information("Event!"); - } - } - } - } -} - \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/Harness.cs b/test/Serilog.PerformanceTests/Harness.cs index 6ba154bba..2ab3e109c 100644 --- a/test/Serilog.PerformanceTests/Harness.cs +++ b/test/Serilog.PerformanceTests/Harness.cs @@ -15,7 +15,6 @@ using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Running; -using Serilog.Tests.Support; using Serilog; using Serilog.Events; using System; @@ -23,46 +22,42 @@ namespace Serilog.PerformanceTests { - // TODO: - - // For Context - // MinimumLevel - // Push - ForContext - // Ctor of LogEvent - // Message Template parsing - - // property binding perf (Bind message template) - - public class Runner + public class Harness { [Fact] - public void ForContext() + public void LogContextEnrichment() { - var context = BenchmarkRunner.Run(); + BenchmarkRunner.Run(); } [Fact] - public void MinimumLevel() + public void MessageTemplateParsing() { - var context = BenchmarkRunner.Run(); + BenchmarkRunner.Run(); } [Fact] - public void FromLogContextPushProperty() + public void LevelControl() + { + BenchmarkRunner.Run(); + } + + [Fact] + public void NestedLoggerCreation() { - var context = BenchmarkRunner.Run(); + BenchmarkRunner.Run(); } [Fact] - public void LogEvent() + public void NestedLoggerLatency() { - var context = BenchmarkRunner.Run(); + BenchmarkRunner.Run(); } [Fact] - public void MessageTemplateParser() + public void Pipeline() { - var context = BenchmarkRunner.Run(); + BenchmarkRunner.Run(); } } } \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/LevelControlBenchmark.cs b/test/Serilog.PerformanceTests/LevelControlBenchmark.cs new file mode 100644 index 000000000..899212357 --- /dev/null +++ b/test/Serilog.PerformanceTests/LevelControlBenchmark.cs @@ -0,0 +1,66 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Running; +using Serilog; +using Serilog.Core; +using Serilog.Events; +using System; +using Serilog.PerformanceTests.Support; +using Xunit; + +namespace Serilog.PerformanceTests +{ + /// + /// Tests the overhead of determining the active logging level. + /// + public class LevelControlBenchmark + { + ILogger _off, _levelSwitchOff, _minLevel, _levelSwitch; + readonly LogEvent _event = Some.InformationEvent(); + + [Setup] + public void Setup() + { + _off = new LoggerConfiguration() + .MinimumLevel.Fatal() + .WriteTo.Sink(new NullSink()) + .CreateLogger(); + _levelSwitchOff = new LoggerConfiguration() + .MinimumLevel.ControlledBy(new LoggingLevelSwitch(LogEventLevel.Fatal)) + .WriteTo.Sink(new NullSink()) + .CreateLogger(); + _minLevel = new LoggerConfiguration() + .MinimumLevel.Information() + .WriteTo.Sink(new NullSink()) + .CreateLogger(); + _levelSwitch = new LoggerConfiguration() + .MinimumLevel.ControlledBy(new LoggingLevelSwitch(LogEventLevel.Information)) + .WriteTo.Sink(new NullSink()) + .CreateLogger(); + } + + [Benchmark(Baseline = true)] + public void Off() + { + _off.Write(_event); + } + + [Benchmark] + public void LevelSwitchOff() + { + _levelSwitchOff.Write(_event); + } + + [Benchmark] + public void MinimumLevelOn() + { + _minLevel.Write(_event); + } + + [Benchmark] + public void LevelSwitchOn() + { + _levelSwitch.Write(_event); + } + } +} + \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/LogContextEnrichmentBenchmark.cs b/test/Serilog.PerformanceTests/LogContextEnrichmentBenchmark.cs new file mode 100644 index 000000000..c353fccfb --- /dev/null +++ b/test/Serilog.PerformanceTests/LogContextEnrichmentBenchmark.cs @@ -0,0 +1,63 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Running; +using Serilog; +using Serilog.Context; +using System; +using Serilog.PerformanceTests.Support; +using Xunit; +using Serilog.Events; + +namespace Serilog.PerformanceTests +{ + public class LogContextEnrichmentBenchmark + { + ILogger _bare, _enriched; + readonly LogEvent _event = Some.InformationEvent(); + + [Setup] + public void Setup() + { + _bare = new LoggerConfiguration() + .WriteTo.Sink(new NullSink()) + .CreateLogger(); + + _enriched = new LoggerConfiguration() + .WriteTo.Sink(new NullSink()) + .Enrich.FromLogContext() + .CreateLogger(); + } + + [Benchmark(Baseline = true)] + public void Bare() + { + _bare.Write(_event); + } + + [Benchmark] + public void PushProperty() + { + using (LogContext.PushProperty("A", "B")) + { + } + } + + [Benchmark] + public void PushPropertyNested() + { + using (LogContext.PushProperty("A", "B")) + using (LogContext.PushProperty("C", "D")) + { + } + } + + [Benchmark] + public void PushPropertyEnriched() + { + using (LogContext.PushProperty("A", "B")) + { + _enriched.Write(_event); + } + } + } +} + \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/LogEventTests.cs b/test/Serilog.PerformanceTests/LogEventTests.cs deleted file mode 100644 index 7f62ff972..000000000 --- a/test/Serilog.PerformanceTests/LogEventTests.cs +++ /dev/null @@ -1,72 +0,0 @@ - -// 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 Serilog.Parsing; -using System; -using System.Linq; -using System.Collections; -using System.Collections.Generic; -using Xunit; - -namespace Serilog.PerformanceTests -{ - public class LogEventTests - { - List _properties; - Exception _exception; - MessageTemplate _emptyMessageTemplate; - - [Setup] - public void Setup() - { - _exception = new Exception("An Error"); - _emptyMessageTemplate = new MessageTemplate(Enumerable.Empty()); - _properties = new List(); - - var items = Enumerable.Range(0,1000); - foreach (var item in items) - { - var prop = new LogEventProperty(item.ToString(), new ScalarValue(item)); - _properties.Add(prop); - } - } - - [Benchmark(Baseline = true)] - public void Baseline() - { - var le = new LogEvent(DateTimeOffset.Now, - LogEventLevel.Information, - _exception, - _emptyMessageTemplate, - Enumerable.Empty()); - } - - [Benchmark()] - public void LogEvent1000Properties() - { - var le = new LogEvent(DateTimeOffset.Now, - LogEventLevel.Information, - _exception, - _emptyMessageTemplate, - _properties); - } - } -} - \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/MessageTemplateParsingBenchmark.cs b/test/Serilog.PerformanceTests/MessageTemplateParsingBenchmark.cs new file mode 100644 index 000000000..d9c3fcfe3 --- /dev/null +++ b/test/Serilog.PerformanceTests/MessageTemplateParsingBenchmark.cs @@ -0,0 +1,41 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Running; +using Serilog; +using Serilog.Events; +using Serilog.Parsing; +using System; +using System.Linq; +using System.Collections; +using System.Collections.Generic; +using Xunit; + +namespace Serilog.PerformanceTests +{ + /// + /// Tests the cost of parsing various message templates. + /// + public class MessageTemplateParsingBenchmark + { + MessageTemplateParser _parser; + const string _DefaultConsoleOutputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}"; + + [Setup] + public void Setup() + { + _parser = new MessageTemplateParser(); + } + + [Benchmark(Baseline = true)] + public void EmptyTemplate() + { + _parser.Parse(""); + } + + [Benchmark] + public void DefaultConsoleOutputTemplate() + { + _parser.Parse(_DefaultConsoleOutputTemplate); + } + } +} + \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/MinimumLevelTests.cs b/test/Serilog.PerformanceTests/MinimumLevelTests.cs deleted file mode 100644 index 6158f2f5c..000000000 --- a/test/Serilog.PerformanceTests/MinimumLevelTests.cs +++ /dev/null @@ -1,152 +0,0 @@ - -// 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 MinimumLevelTests - { - ILogger log; - 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/NestedLoggerCreationBenchmark.cs b/test/Serilog.PerformanceTests/NestedLoggerCreationBenchmark.cs new file mode 100644 index 000000000..1c170d366 --- /dev/null +++ b/test/Serilog.PerformanceTests/NestedLoggerCreationBenchmark.cs @@ -0,0 +1,33 @@ +using BenchmarkDotNet.Attributes; +using Serilog.PerformanceTests.Support; + +namespace Serilog.PerformanceTests +{ + /// + /// Tests the cost creating a nested logger. + /// + public class NestedLoggerCreationBenchmark + { + ILogger log; + + [Setup] + public void Setup() + { + log = new LoggerConfiguration() + .WriteTo.Sink(new NullSink()) + .CreateLogger(); + } + + [Benchmark] + public void ForContextString() + { + log.ForContext("SourceContext", "Serilog.PerformanceTests"); + } + + [Benchmark] + public void ForContextType() + { + log.ForContext(); + } + } +} \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/NestedLoggerLatencyBenchmark.cs b/test/Serilog.PerformanceTests/NestedLoggerLatencyBenchmark.cs new file mode 100644 index 000000000..537a60371 --- /dev/null +++ b/test/Serilog.PerformanceTests/NestedLoggerLatencyBenchmark.cs @@ -0,0 +1,42 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Running; +using Serilog; +using System; +using Serilog.PerformanceTests.Support; +using Xunit; +using Serilog.Events; + +namespace Serilog.PerformanceTests +{ + /// + /// Tests the overhead of writing through a nested logger. + /// + public class NestedLoggerLatencyBenchmark + { + ILogger _log, _nested; + readonly LogEvent _event = Some.InformationEvent(); + + [Setup] + public void Setup() + { + _log = new LoggerConfiguration() + .WriteTo.Sink(new NullSink()) + .CreateLogger(); + + _nested = _log.ForContext(); + } + + [Benchmark(Baseline = true)] + public void RootLogger() + { + _log.Write(_event); + } + + [Benchmark] + public void NestedLogger() + { + _nested.Write(_event); + } + } +} + \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/MessageTemplateParserTests.cs b/test/Serilog.PerformanceTests/PipelineBenchmark.cs similarity index 60% rename from test/Serilog.PerformanceTests/MessageTemplateParserTests.cs rename to test/Serilog.PerformanceTests/PipelineBenchmark.cs index c124fe99f..6812f2345 100644 --- a/test/Serilog.PerformanceTests/MessageTemplateParserTests.cs +++ b/test/Serilog.PerformanceTests/PipelineBenchmark.cs @@ -15,7 +15,6 @@ using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Running; -using Serilog.Tests.Support; using Serilog; using Serilog.Events; using Serilog.Parsing; @@ -23,32 +22,36 @@ using System.Linq; using System.Collections; using System.Collections.Generic; +using Serilog.PerformanceTests.Support; using Xunit; namespace Serilog.PerformanceTests { - public class MessageTemplateParserTests - { - MessageTemplateParser _parser; - const string DefaultConsoleOutputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}"; + /// + /// Tests the cost of writing through the logging pipeline. + /// + public class PipelineBenchmark + { + ILogger _log; + Exception _exception; [Setup] public void Setup() { - _parser = new MessageTemplateParser(); - } + _exception = new Exception("An Error"); + _log = new LoggerConfiguration() + .WriteTo.Sink(new NullSink()) + .CreateLogger(); - [Benchmark(Baseline = true)] - public void Baseline() - { - var template = _parser.Parse(""); - } + // Ensure template is cached + _log.Information(_exception, "Hello, {Name}!", "World"); + } [Benchmark] - public void ParseDefaultConsoleOutputTemplate() + public void EmitLogEvent() { - var template = _parser.Parse(DefaultConsoleOutputTemplate); - } + _log.Information(_exception, "Hello, {Name}!", "World"); + } } } \ No newline at end of file diff --git a/test/Serilog.PerformanceTests/Support/NullSink.cs b/test/Serilog.PerformanceTests/Support/NullSink.cs new file mode 100644 index 000000000..14432a21a --- /dev/null +++ b/test/Serilog.PerformanceTests/Support/NullSink.cs @@ -0,0 +1,12 @@ +using Serilog.Events; +using Serilog.Core; + +namespace Serilog.PerformanceTests.Support +{ + class NullSink : ILogEventSink + { + public void Emit(LogEvent logEvent) + { + } + } +} diff --git a/test/Serilog.PerformanceTests/Support/Some.cs b/test/Serilog.PerformanceTests/Support/Some.cs new file mode 100644 index 000000000..07fbf5aab --- /dev/null +++ b/test/Serilog.PerformanceTests/Support/Some.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using Serilog.Events; +using Serilog.Parsing; + +namespace Serilog.PerformanceTests.Support +{ + static class Some + { + public static LogEvent InformationEvent() + { + return new LogEvent(DateTime.Now, LogEventLevel.Information, + null, new MessageTemplate(Enumerable.Empty()), Enumerable.Empty()); + } + + } +} diff --git a/test/Serilog.PerformanceTests/project.json b/test/Serilog.PerformanceTests/project.json index 65d6ef403..2ebb7562c 100755 --- a/test/Serilog.PerformanceTests/project.json +++ b/test/Serilog.PerformanceTests/project.json @@ -3,11 +3,9 @@ "dependencies": { "Serilog": { "target": "project" }, - "Serilog.Tests": { "target": "project" }, - "TestDummies": { "target": "project" }, "xunit": "2.1.0", "dotnet-test-xunit": "1.0.0-rc2-build10025", - "BenchmarkDotNet": "0.9.7-beta" + "BenchmarkDotNet": "0.9.9" }, "buildOptions": { "keyFile": "../../assets/Serilog.snk"