Add documentation about reusing contract resolvers (#1785)

This commit is contained in:
James Newton-King
2018-08-04 16:30:23 +12:00
committed by GitHub
parent 27c4eb88f6
commit 55f9ec3ab1
3 changed files with 53 additions and 0 deletions
+3
View File
@@ -14,6 +14,9 @@
<para>Anything that can be set on an object, collection, property, etc, using attributes or methods to control serialization
can also be set using an IContractResolver.</para>
<autoOutline lead="none" excludeRelatedTopics="true" />
<alert class="note">
<para>For performance you should create a contract resolver once and reuse instances when possible. Resolving contracts is slow and implementations of <codeEntityReference>T:Newtonsoft.Json.Serialization.IContractResolver</codeEntityReference> typically cache contracts.</para>
</alert>
</introduction>
<!-- Add one or more top-level section elements. These are collapsible.
If using <autoOutline />, add an address attribute to identify it
+14
View File
@@ -6,6 +6,20 @@
Here are some tips to make it go even faster.</para>
<autoOutline lead="none" excludeRelatedTopics="true" />
</introduction>
<section address="ReuseContractResolver">
<title>Reuse Contract Resolver</title>
<content>
<para>The <codeEntityReference>T:Newtonsoft.Json.Serialization.IContractResolver</codeEntityReference> resolves .NET types to contracts that are used during serialization inside JsonSerializer.
Creating a contract involves inspecting a type with slow reflection, so contracts are typically
cached by implementations of IContractResolver like <codeEntityReference>T:Newtonsoft.Json.Serialization.DefaultContractResolver</codeEntityReference>.</para>
<para>To avoid the overhead of recreating contracts every time you use JsonSerializer you should create the contract resolver once and reuse it.
Note that if you are not using a contract resolver then a shared internal instance is automatically used when serializing and deserializing.
</para>
<code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\PerformanceTests.cs" region="ReuseContractResolver" title="Reuse ContractResolver" />
</content>
</section>
<section address="MemoryUsage">
<title>Optimize Memory Usage</title>
<content>
@@ -111,6 +111,42 @@ namespace Newtonsoft.Json.Tests.Documentation
[TestFixture]
public class PerformanceTests : TestFixtureBase
{
private static class AppSettings
{
public static readonly IContractResolver SnakeCaseContractResolver = new DefaultContractResolver();
}
[Test]
public void ReuseContractResolverTest()
{
Person person = new Person();
#region ReuseContractResolver
// BAD - a new contract resolver is created each time, forcing slow reflection to be used
string json1 = JsonConvert.SerializeObject(person, new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
}
});
// GOOD - reuse the contract resolver from a shared location
string json2 = JsonConvert.SerializeObject(person, new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ContractResolver = AppSettings.SnakeCaseContractResolver
});
// GOOD - an internal contract resolver is used
string json3 = JsonConvert.SerializeObject(person, new JsonSerializerSettings
{
Formatting = Formatting.Indented
});
#endregion
}
[Test]
public void ConverterContractResolverTest()
{