Skip to content

Commit

Permalink
Fix inefficient branching in MessagePackZLoggerFormatter
Browse files Browse the repository at this point in the history
  • Loading branch information
hadashiA committed Oct 20, 2023
1 parent d4229c5 commit b0dae24
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 201 deletions.
288 changes: 95 additions & 193 deletions src/ZLogger.MessagePack/MessagePackZLoggerFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public static ZLoggerOptions UseMessagePackFormatter(this ZLoggerOptions options
});
}
}

public class MessagePackZLoggerFormatter : IZLoggerFormatter
{
// "CategoryName"
Expand Down Expand Up @@ -111,7 +111,7 @@ public void FormatLogEntry<TEntry>(IBufferWriter<byte> writer, TEntry entry) whe
messagePackWriter.WriteRaw(ExceptionKey);
WriteException(ref messagePackWriter, ex);
}

for (var i = 0; i < entry.ParameterCount; i++)
{
if (entry.IsSupportUtf8ParameterKey)
Expand All @@ -124,197 +124,8 @@ public void FormatLogEntry<TEntry>(IBufferWriter<byte> writer, TEntry entry) whe
var key = entry.GetParameterKeyAsString(i);
messagePackWriter.Write(key);
}

var valueType = entry.GetParameterType(i);
if (valueType == typeof(string))
{
messagePackWriter.Write(entry.GetParameterValue<string>(i));
}
else if (valueType == typeof(bool))
{
messagePackWriter.Write(entry.GetParameterValue<bool>(i));
}
else if (valueType == typeof(bool?))
{
var nullableValue = entry.GetParameterValue<bool?>(i);
if (nullableValue.HasValue)
{
messagePackWriter.Write(nullableValue.Value);
}
else
{
messagePackWriter.WriteNil();
}
}
else if (valueType == typeof(byte))
{
messagePackWriter.Write(entry.GetParameterValue<byte>(i));
}
else if (valueType == typeof(byte?))
{
var nullableValue = entry.GetParameterValue<byte?>(i);
if (nullableValue.HasValue)
{
messagePackWriter.Write(nullableValue.Value);
}
else
{
messagePackWriter.WriteNil();
}
}
else if (valueType == typeof(Int16))
{
messagePackWriter.Write(entry.GetParameterValue<Int16>(i));
}
else if (valueType == typeof(Int16?))
{
var nullableValue = entry.GetParameterValue<Int16?>(i);
if (nullableValue.HasValue)
{
messagePackWriter.Write(nullableValue.Value);
}
else
{
messagePackWriter.WriteNil();
}
}
else if (valueType == typeof(UInt16))
{
messagePackWriter.Write(entry.GetParameterValue<UInt16>(i));
}
else if (valueType == typeof(UInt16?))
{
var nullableValue = entry.GetParameterValue<UInt16?>(i);
if (nullableValue.HasValue)
{
messagePackWriter.Write(nullableValue.Value);
}
else
{
messagePackWriter.WriteNil();
}
}
else if (valueType == typeof(Int32))
{
messagePackWriter.Write(entry.GetParameterValue<Int32>(i));
}
else if (valueType == typeof(Int32?))
{
var nullableValue = entry.GetParameterValue<Int32?>(i);
if (nullableValue.HasValue)
{
messagePackWriter.Write(nullableValue.Value);
}
else
{
messagePackWriter.WriteNil();
}
}
else if (valueType == typeof(UInt32))
{
messagePackWriter.Write(entry.GetParameterValue<UInt32>(i));
}
else if (valueType == typeof(UInt32?))
{
var nullableValue = entry.GetParameterValue<UInt32?>(i);
if (nullableValue.HasValue)
{
messagePackWriter.Write(nullableValue.Value);
}
else
{
messagePackWriter.WriteNil();
}
}
else if (valueType == typeof(Int64))
{
messagePackWriter.Write(entry.GetParameterValue<Int64>(i));
}
else if (valueType == typeof(Int64?))
{
var nullableValue = entry.GetParameterValue<Int64?>(i);
if (nullableValue.HasValue)
{
messagePackWriter.Write(nullableValue.Value);
}
else
{
messagePackWriter.WriteNil();
}
}
else if (valueType == typeof(UInt64))
{
messagePackWriter.Write(entry.GetParameterValue<UInt64>(i));
}
else if (valueType == typeof(UInt16?))
{
var nullableValue = entry.GetParameterValue<UInt16?>(i);
if (nullableValue.HasValue)
{
messagePackWriter.Write(nullableValue.Value);
}
else
{
messagePackWriter.WriteNil();
}
}
else if (valueType == typeof(float))
{
messagePackWriter.Write(entry.GetParameterValue<float>(i));
}
else if (valueType == typeof(float?))
{
var nullableValue = entry.GetParameterValue<float?>(i);
if (nullableValue.HasValue)
{
messagePackWriter.Write(nullableValue.Value);
}
else
{
messagePackWriter.WriteNil();
}
}
else if (valueType == typeof(double))
{
messagePackWriter.Write(entry.GetParameterValue<double>(i));
}
else if (valueType == typeof(double?))
{
var nullableValue = entry.GetParameterValue<double?>(i);
if (nullableValue.HasValue)
{
messagePackWriter.Write(nullableValue.Value);
}
else
{
messagePackWriter.WriteNil();
}
}
else if (valueType == typeof(DateTime))
{
var value = entry.GetParameterValue<DateTime>(i);
MessagePackSerializer.Serialize(valueType, ref messagePackWriter, value, MessagePackSerializerOptions);
}
else if (valueType == typeof(DateTime?))
{
var value = entry.GetParameterValue<DateTime?>(i);
MessagePackSerializer.Serialize(valueType, ref messagePackWriter, value, MessagePackSerializerOptions);
}
else if (valueType == typeof(DateTimeOffset))
{
var value = entry.GetParameterValue<DateTimeOffset>(i);
MessagePackSerializer.Serialize(valueType, ref messagePackWriter, value, MessagePackSerializerOptions);
}
else if (valueType == typeof(DateTimeOffset?))
{
var value = entry.GetParameterValue<DateTimeOffset?>(i);
MessagePackSerializer.Serialize(valueType, ref messagePackWriter, value, MessagePackSerializerOptions);
}
else // TODO: GUID, TimeSpan
{
var boxedValue = entry.GetParameterValue(i);
MessagePackSerializer.Serialize(valueType, ref messagePackWriter, boxedValue, MessagePackSerializerOptions);
}

WriteParameterValue(ref messagePackWriter, entry, entry.GetParameterType(i), i);
}

if (entry.ScopeState != null)
Expand Down Expand Up @@ -364,6 +175,97 @@ static void WriteException(ref MessagePackWriter messagePackWriter, Exception? e
WriteException(ref messagePackWriter, ex.InnerException);
}

void WriteParameterValue<TEntry>(ref MessagePackWriter messagePackWriter, TEntry entry, Type type, int index)
where TEntry : IZLoggerEntry
{
var code = Type.GetTypeCode(type);
switch (code)
{
case TypeCode.Boolean:
messagePackWriter.Write(entry.GetParameterValue<bool>(index));
return;
case TypeCode.Char:
messagePackWriter.Write(entry.GetParameterValue<char>(index));
return;
case TypeCode.SByte:
messagePackWriter.Write(entry.GetParameterValue<sbyte>(index));
return;
case TypeCode.Byte:
messagePackWriter.Write(entry.GetParameterValue<byte>(index));
return;
case TypeCode.Int16:
messagePackWriter.Write(entry.GetParameterValue<Int16>(index));
return;
case TypeCode.UInt16:
messagePackWriter.Write(entry.GetParameterValue<UInt16>(index));
return;
case TypeCode.Int32:
messagePackWriter.Write(entry.GetParameterValue<Int32>(index));
return;
case TypeCode.UInt32:
messagePackWriter.Write(entry.GetParameterValue<UInt32>(index));
return;
case TypeCode.Int64:
messagePackWriter.Write(entry.GetParameterValue<Int64>(index));
return;
case TypeCode.UInt64:
messagePackWriter.Write(entry.GetParameterValue<UInt64>(index));
return;
case TypeCode.Single:
messagePackWriter.Write(entry.GetParameterValue<Single>(index));
return;
case TypeCode.Double:
messagePackWriter.Write(entry.GetParameterValue<double>(index));
return;
case TypeCode.DateTime:
return;
case TypeCode.String:
messagePackWriter.Write(entry.GetParameterValue<string>(index));
return;
}

if (type.IsValueType)
{
if (type == typeof(DateTime))
{
var value = entry.GetParameterValue<DateTime>(index);
MessagePackSerializer.Serialize(type, ref messagePackWriter, value, MessagePackSerializerOptions);
}
else if (type == typeof(DateTimeOffset))
{
var value = entry.GetParameterValue<DateTimeOffset>(index);
MessagePackSerializer.Serialize(type, ref messagePackWriter, value, MessagePackSerializerOptions);
}
else if (type == typeof(TimeSpan))
{
var value = entry.GetParameterValue<TimeSpan>(index);
MessagePackSerializer.Serialize(type, ref messagePackWriter, value, MessagePackSerializerOptions);
}
else if (type == typeof(Guid))
{
var value = entry.GetParameterValue<Guid>(index);
MessagePackSerializer.Serialize(type, ref messagePackWriter, value, MessagePackSerializerOptions);
}
// FIXME: If type is Nullable<T> and value is null, (T?)p.BoxedValue returns default(T). not null.
// else if (Nullable.GetUnderlyingType(type) is { } underlyingType)
// {
// WriteParameterValue(ref messagePackWriter, entry, underlyingType, index);
// }

// TODO: enum. But if MagicalBox is not used directly, a more efficient way than MessagePackSerializer call must be considered.
}

var boxedValue = entry.GetParameterValue(index);
if (boxedValue == null)
{
messagePackWriter.WriteNil();
}
else
{
MessagePackSerializer.Serialize(type, ref messagePackWriter, boxedValue, MessagePackSerializerOptions);
}
}

static byte[] EncodedLogLevel(LogLevel logLevel)
{
switch (logLevel)
Expand Down
2 changes: 1 addition & 1 deletion src/ZLogger.MessagePack/ZLogger.MessagePack.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</PropertyGroup>

<ItemGroup>
<None Include="Icon.png" Pack="true" PackagePath="/" />
<None Include="..\ZLogger\Icon.png" Pack="true" PackagePath="/" />
</ItemGroup>

<ItemGroup>
Expand Down
10 changes: 7 additions & 3 deletions tests/ZLogger.MessagePack.Tests/FormatterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,24 @@ public void WithExceptionWithInnerException()
}

[Fact]
public void WithPayload()
public void WithParameter()
{
var now = DateTime.UtcNow;
var payload = new TestPayload { X = 999 };
logger.ZLogInformation(new EventId(1, "HOGE"), $"UMU {payload}");
int? x = 100;
int? y = null;
logger.ZLogInformation(new EventId(1, "HOGE"), $"UMU {x} {y}");

var msgpack = processor.Dequeue();
((string)msgpack["CategoryName"]).Should().Be("test");
((string)msgpack["LogLevel"]).Should().Be("Information");
((int)msgpack["EventId"]).Should().Be(1);
((string)msgpack["EventIdName"]).Should().Be("HOGE");
((DateTime)msgpack["Timestamp"]).Should().BeOnOrAfter(now);
((int?)msgpack["x"]).Should().Be(100);
((int?)msgpack["y"]).Should().Be(null);
((int)msgpack["payload"]["x"]).Should().Be(999);
((bool)msgpack.ContainsKey("Exception")).Should().BeFalse();
}
}
}
}
4 changes: 0 additions & 4 deletions tests/ZLogger.Tests/EnumDictionaryTest.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Xunit;
using ZLogger.Internal;

namespace ZLogger.Tests
Expand Down

0 comments on commit b0dae24

Please sign in to comment.