-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
JsonSerializer - Serialize Object Properties into StringBuilder #2179
JsonSerializer - Serialize Object Properties into StringBuilder #2179
Conversation
401727a
to
c07d817
Compare
Codecov Report
@@ Coverage Diff @@
## master #2179 +/- ##
=======================================
- Coverage 82% 82% -<1%
=======================================
Files 300 304 +4
Lines 20623 21154 +531
Branches 2483 2537 +54
=======================================
+ Hits 16853 17282 +429
- Misses 3150 3236 +86
- Partials 620 636 +16 |
9134aba
to
89cc2d2
Compare
89cc2d2
to
37b4528
Compare
b7f8f2f
to
638a699
Compare
@304NotModified Have implemented a simple MruCache and optimized for using StringBuilder by default. |
638a699
to
3b77913
Compare
👍 👍 will try to review it this weekend |
decb48e
to
a3f3d44
Compare
Made a small performance test using a simple DTO with 3 properties (string, integer, enum). And it could serialize 1.000.000 items per second (with very little allocation). Not the fastest in the world, but should cover the needs of NLog. |
a3f3d44
to
8c2ef71
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! Reviewed it!
src/NLog/Internal/MruCache.cs
Outdated
|
||
if (_dictionary.Count >= _maxCapacity) | ||
{ | ||
_dictionary.Clear(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do this before the delete prune?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With different check of course
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _dictionary.Clear();
is a fail safe, in case something has gone terrible wrong, and all items has the same version.
} | ||
else | ||
{ | ||
var version = ++_currentVersion; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Postfix ++?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want "version" to have the updated value. I guess I could write:
var version = _currentVersion += 1 ;
item = default(MruItem); // Too many people in the same room | ||
} | ||
|
||
if (item.Version != _currentVersion) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please some docs here, thanks! (I guess retrieving the sane is here on purpose)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/NLog/Layouts/JsonLayout.cs
Outdated
{ | ||
var jsonSerializer = ConfigurationItemFactory.Default.JsonSerializer; | ||
_jsonSerializer = jsonSerializer as NLog.Targets.IJsonSerializerV2; | ||
if (_jsonSerializer == null && jsonSerializer != null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe nicer if we fix this in the setter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well it is lazy-initialization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair enough :)
} | ||
|
||
private static bool IsNumericTypeCode(TypeCode objTypeCode) | ||
private static bool IsNumericTypeCode(TypeCode objTypeCode, bool includeDecimals) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add some docs why include decimals could be false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/NLog/Targets/IJsonSerializer.cs
Outdated
/// </summary> | ||
/// <param name="value">The object to serialize to JSON.</param> | ||
/// <param name="builder">Output destination.</param> | ||
bool SerializeObject(object value, System.Text.StringBuilder builder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please document the output value. Is it true if success?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/NLog/Targets/IJsonSerializer.cs
Outdated
@@ -49,4 +49,15 @@ public interface IJsonSerializer | |||
/// <returns>Serialized value.</returns> | |||
string SerializeObject(object value); | |||
} | |||
|
|||
internal interface IJsonSerializerV2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be public and in the NLog namespace, what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to have it public, as it would allow others to optimize for StringBuilder. Not sure about the naming-convention though, by making it internal, then I could just choose a "random" name :).
Maybe we have to include also some more test cases. 126 missed lines could be better |
13c3e86
to
1f98a75
Compare
f6b60d0
to
9c50e98
Compare
9c50e98
to
2d5baf8
Compare
src/NLog/Targets/IJsonSerializer.cs
Outdated
string SerializeObject(object value); | ||
} | ||
|
||
internal interface IJsonSerializerV2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ow a commit has not been added from mobile...
I think it's important to have the interface public, maybe we could move it to the "NLog" namespace? (and mark the other as obsolete)
While the default serialization is good enough for most cases, it should be possible to replace it with e.g. JSON.NET
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it will not be super optimal for Json.Net as the implementation would be:
bool SerializeObject(object value, System.Text.StringBuilder sb)
{
int originalLength = sb.Length;
try
{
StringWriter sw = new StringWriter(sb);
JsonSerializer serializer = new JsonSerializer();
using (JsonWriter jsonTextWriter = new JsonTextWriter(sw))
{
serializer.Serialize(jsonTextWriter, obj);
}
return true;
}
catch
{
sb.Length = originalLength;
return false;
}
}
85df7af
to
20f5c75
Compare
@304NotModified I have now introduced NLog.IJsonConverter and marked NLog.Targets.IJsonSerializer as obsolete. |
08b12aa
to
865abcd
Compare
Converts object to JSON-string :). Feel free to provide any interface name you want |
865abcd
to
062ec3f
Compare
Now fixed the obsolete-text to say NLog.IJsonConverter. Good catch. |
I think its better to give the hint of the change property instead of the interface in the obsolete text. Have updated it. |
merged! Thanks! |
Prototype of how one could extend Json Serializer to handle object-properties.
Stolen the unit tests from #2128