Skip to content
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

Merged
merged 7 commits into from
Jun 28, 2017

Conversation

snakefoot
Copy link
Contributor

@snakefoot snakefoot commented Jun 19, 2017

Prototype of how one could extend Json Serializer to handle object-properties.

Stolen the unit tests from #2128

@snakefoot snakefoot force-pushed the JsonSerializeObjectProperties branch 3 times, most recently from 401727a to c07d817 Compare June 19, 2017 23:42
@codecov
Copy link

codecov bot commented Jun 19, 2017

Codecov Report

Merging #2179 into master will decrease coverage by <1%.
The diff coverage is 80%.

@@           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

@snakefoot snakefoot force-pushed the JsonSerializeObjectProperties branch 4 times, most recently from 9134aba to 89cc2d2 Compare June 20, 2017 21:27
@snakefoot snakefoot force-pushed the JsonSerializeObjectProperties branch from 89cc2d2 to 37b4528 Compare June 21, 2017 05:09
@snakefoot snakefoot force-pushed the JsonSerializeObjectProperties branch from b7f8f2f to 638a699 Compare June 21, 2017 21:32
@snakefoot
Copy link
Contributor Author

@304NotModified Have implemented a simple MruCache and optimized for using StringBuilder by default.

@snakefoot snakefoot force-pushed the JsonSerializeObjectProperties branch from 638a699 to 3b77913 Compare June 21, 2017 21:46
@304NotModified
Copy link
Member

👍 👍 will try to review it this weekend

@snakefoot snakefoot force-pushed the JsonSerializeObjectProperties branch 7 times, most recently from decb48e to a3f3d44 Compare June 22, 2017 18:37
@snakefoot
Copy link
Contributor Author

snakefoot commented Jun 22, 2017

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.

@snakefoot snakefoot force-pushed the JsonSerializeObjectProperties branch from a3f3d44 to 8c2ef71 Compare June 22, 2017 18:55
Copy link
Member

@304NotModified 304NotModified left a 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!


if (_dictionary.Count >= _maxCapacity)
{
_dictionary.Clear();
Copy link
Member

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?

Copy link
Member

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

Copy link
Contributor Author

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;
Copy link
Member

Choose a reason for hiding this comment

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

Postfix ++?

Copy link
Contributor Author

@snakefoot snakefoot Jun 22, 2017

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)
Copy link
Member

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)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

{
var jsonSerializer = ConfigurationItemFactory.Default.JsonSerializer;
_jsonSerializer = jsonSerializer as NLog.Targets.IJsonSerializerV2;
if (_jsonSerializer == null && jsonSerializer != null)
Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Member

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)
Copy link
Member

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

/// </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);
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -49,4 +49,15 @@ public interface IJsonSerializer
/// <returns>Serialized value.</returns>
string SerializeObject(object value);
}

internal interface IJsonSerializerV2
Copy link
Member

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?

Copy link
Contributor Author

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 :).

@304NotModified
Copy link
Member

Maybe we have to include also some more test cases. 126 missed lines could be better

@snakefoot snakefoot force-pushed the JsonSerializeObjectProperties branch 2 times, most recently from 13c3e86 to 1f98a75 Compare June 22, 2017 20:59
@snakefoot snakefoot force-pushed the JsonSerializeObjectProperties branch from f6b60d0 to 9c50e98 Compare June 22, 2017 22:23
@snakefoot snakefoot force-pushed the JsonSerializeObjectProperties branch from 9c50e98 to 2d5baf8 Compare June 22, 2017 22:35
string SerializeObject(object value);
}

internal interface IJsonSerializerV2
Copy link
Member

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

Copy link
Contributor Author

@snakefoot snakefoot Jun 25, 2017

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;
   }
}

@snakefoot
Copy link
Contributor Author

snakefoot commented Jun 25, 2017

@304NotModified I have now introduced NLog.IJsonConverter and marked NLog.Targets.IJsonSerializer as obsolete.

@snakefoot snakefoot force-pushed the JsonSerializeObjectProperties branch 4 times, most recently from 08b12aa to 865abcd Compare June 25, 2017 22:15
@snakefoot
Copy link
Contributor Author

snakefoot commented Jun 25, 2017

IJsonConverter?

Converts object to JSON-string :). Feel free to provide any interface name you want

@snakefoot snakefoot force-pushed the JsonSerializeObjectProperties branch from 865abcd to 062ec3f Compare June 25, 2017 22:27
@snakefoot
Copy link
Contributor Author

Now fixed the obsolete-text to say NLog.IJsonConverter. Good catch.

@304NotModified
Copy link
Member

I think its better to give the hint of the change property instead of the interface in the obsolete text. Have updated it.

@304NotModified 304NotModified added this to the 4.5 milestone Jun 28, 2017
@304NotModified 304NotModified merged commit 7399c93 into NLog:master Jun 28, 2017
@304NotModified
Copy link
Member

merged! Thanks!

@304NotModified 304NotModified modified the milestones: 4.5, 4.5 beta ? Oct 10, 2017
@snakefoot snakefoot deleted the JsonSerializeObjectProperties branch October 10, 2017 20:42
@snakefoot snakefoot mentioned this pull request Nov 23, 2017
@snakefoot snakefoot modified the milestones: 4.5 beta ?, 4.5 Aug 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants