📜 ⬆️ ⬇️

Performance Comparison JSON-serializer for .NET

Json in .NET can be used for different purposes. In my case, this is the formation of a response to an Ajax request in an ASP.NET Mvc application. Of course, converting a response in JSON - not the thin place, but I was curious about how you can speed up this operation. This article is not a detailed review of existing JSON-serializer for .NET / Mono. I was primarily interested in the time required to serialize the relatively simple data structures, and secondarily mapping. That is, it would be desirable that serialization was easily and flexibly programmed and quickly worked.

The following serialization tools were used in the study:
  1. Simple string concatenation
  2. JavaScriptSerializer (.NET Framework)
  3. DataContractJsonSerializer (.NET Framework 3.5)
  4. Newton Json.net ( json.codeplex.com , james.newtonking.com/pages/json-net.aspx )
  5. JsonEx ( code.google.com/p/jsonexserializer )
  6. Json Fluent ( fluentjson.codeplex.com , code.google.com/p/fluent-json )


To measure performance, two types of tests were performed:
Test number 1. The serializer was initialized 10,000 times and the same object was serialized.

Test number 2. 1 time create and initialize the serializer. 10,000 times serialization was performed. The test was conceived with the hope that the “smart” serializer, having received in advance information about the type of object, will perform the conversion faster. In some cases, preliminary initialization is impossible, then the results of such tests will be marked with a dash.
')
Testing Environment:
Among the subjects there are two classes that are included in the platform, which means that there may be differences in their work in Mono and .NET. As the main and the only OS I have Ubuntu, so to test I used the .NET VM VirtualBox. And to be precise:

String concatenation


The first thing I will give the results of testing by a simple serialization ToString () and concatenation. In the "production" this method can be justified only in rare cases. I consider it to be used as a reference. It’s hard to think of a way to get a JSON string faster.
Test results below:
Test number 1Test number 2
.NET0.25 sec-
Mono0.6 sec-

Carrying out the test â„–2, for obvious reasons, it is impossible.

JavaScriptSerializer


JavaScriptSerializer is namespace System.Web.Script.Serialization .NET / Mono platforms. Code example:
var serializer = new JavaScriptSerializer();// string jsonResult = serializer.Serialize(Program.bookA);// 


Declared the ability to override the ways of serialization for different data types using the classes JavaScriptConverter, RegisterConverters. This can be useful, for example, for converting DateTime or enums. Tests were conducted without using this feature.

Test results:
Test number 1Test number 2
.NET4 sec3.5 seconds
Mono5 sec5 sec


DataContractJsonSerializer


Another serializer available out of the box is in the System.Runtime.Serialization.Json namespace. In use, it hardly differs from the previous one, except that the serialization takes place in stream, not in a string. Example:
 var serializer = new DataContractJsonSerializer(typeof(Book)); MemoryStream ms = new MemoryStream(); serializer.WriteObject(ms, Program.bookA); string jsonResult = Encoding.Default.GetString(ms.GetBuffer()); 


There are differences in the use of this tool in the .NET and Mono. In .NET, you must mark the classes and properties being serialized by the [DataContract] and [DataMember] attributes, respectively. In Mono, these attributes are optional.
Test results show that the difference is not only in the attributes:
Test number 1Test number 2
.NET1.5 seconds1.5 seconds
Mono34 sec34 sec

Looking ahead, I will say 1.5 seconds - this is the best time among all the subjects, 34 seconds - the worst.

Fluent json


The advantage (and to whom and disadvantage) of this serializer is that it provides a flexible way of mapping properties. There is no need to enter attributes into the business logic layer, which is problematic when working with third-party libraries. No intermediate classes are needed to convert the data structures of the business logic layer to the data structures of the client-server exchange. Another of the declared "chips" is the possibility of multi-threaded processing of large data sets, which gives high performance. Not my case.

The sample code below shows how this works:
 var serializer = Json.EnoderFor<Book>(config => config .MapType<Book>(map => map .AllFields() .Field<DateTime>(field => field.PubDate, pubDate => pubDate .EncodeAs<string>(value => value.ToShortDateString())) .Field<BookType>(field => field.Type, type => type .EncodeAs<int>(value => (int)value) .To("book_type"))) .MapType<Author>(map => map.AllFields()) .UseTidy(true) ); string jsonResult = serializer.Enode(Program.bookA); 


If the data type being serialized contains properties like enumeration or DateTime, as in the example above, then it is necessary to specify the conversion for them. Fluent Json alone won’t know what to do with them.

Test results:
Test number 1Test number 2
.NET52.5 seconds9 sec
Mono34 sec10 sec

JsonExSerializer


According to the developer, this tool is designed for accurate serialization / deserialization of objects that other libraries do not provide. For me, this is not the most important thing, I will test for speed. Code example:
 var serializer = new Serializer(typeof(Book)); var memoryStream = new MemoryStream(); serializer.Serialize(Program.bookA, memoryStream); var jsonResult = Encoding.Default.GetString(memoryStream.GetBuffer()); 


A piquant feature of JsonEx is that it adds formatting and a comment to the result:
 /* Created by JsonExSerializer Assembly: JsonTestConsole, Version=1.0.4347.32516, Culture=neutral, PublicKeyToken=null Type: JsonTestConsole.Book */ 

Formatting can be useful when saving, for example, settings to a file, which can later be edited in a text editor.

Test results:
Test number 1Test number 2
.NET32 seconds8 sec
Mono34 sec10 sec

newton JSON.NET


In the description of the features there is an intriguing line "High performance, faster than .NET's built-in JSON serializers". Sample code using Newton fits into one line:
 string jsonResult = JsonConvert.SerializeObject(Program.bookA); 


It does not require any preliminary initialization, but it shows a very good time:
Test number 1Test number 2
.NET1.5 sec-
Mono2 sec-


Conclusion


The test results sorted by ascending time (in milliseconds) for both configurations (K column shows how many times the "concatenation" test is slower):

PlatformMono.Net Framework
serializerTest number 1Test number 2KTest number 1Test number 2K
String concatination600-one250-one
newton JSON.NET2,000-3.41,500-6
JavaScriptSerializer5,0004,0008.3 / 6.7170017006.8
JsonExSerializer34,00010,00056.7 / 16.74,0003,50016/14
Fluent json34,00010,00056.7 / 16.732,0008,000128/32
DataContractJsonSerializer34,00034,00056.7 / 56.71,5001,5006

The table shows that if there are plans to drive a Mono application or platform is not defined, it is best to turn to a third-party library Newton JSON.net - it shows good results both in the Win + .NET and Linux + Mono. If the target .NET platform and attribute binding are not confused, the built-in DataContractJsonSerializer is sufficient. If both options are not satisfied, you can invent your own library - there is much to strive for.

Test code here: code.google.com/p/research-net-json/source/browse/Main.cs . Third-party libraries will have to extort themselves, once again the links:


UPD. Is complemented by a few more tests serializers (thanks atd , skyboy , Guderian and kekekeks ):
PlatformMono.Net Framework
SerializerTest number 1Test number 2KTest number 1Test number 2K
new StringBuilder (400)550-0.9270-one
ServiceStack1,300-2.21200-4.8
Fast Json2,600-4.31200-4.8
Jayrock8,200-13.79200-36.8

As you can see, there's a new leader - ServiceStack.

PS If you have noticed an error, or you know other libraries, write, I will gladly supplement the article.

Source: https://habr.com/ru/post/133778/


All Articles