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:- Simple string concatenation
- JavaScriptSerializer (.NET Framework)
- DataContractJsonSerializer (.NET Framework 3.5)
- Newton Json.net ( json.codeplex.com , james.newtonking.com/pages/json-net.aspx )
- JsonEx ( code.google.com/p/jsonexserializer )
- 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:
- Configuration "mono": Intel Atom 330, 4Gb + Ubuntu 10.10, MonoDevelop 2.6, Mono 2.10.5
- Configuration «.NET»: VirtualBox, 1.5GB, Windows XP, VS2010, .NET Framework 3.5
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 1 | Test number 2 |
.NET | 0.25 sec | - |
Mono | 0.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();
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 1 | Test number 2 |
.NET | 4 sec | 3.5 seconds |
Mono | 5 sec | 5 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 1 | Test number 2 |
.NET | 1.5 seconds | 1.5 seconds |
Mono | 34 sec | 34 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 1 | Test number 2 |
.NET | 52.5 seconds | 9 sec |
Mono | 34 sec | 10 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:
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 1 | Test number 2 |
.NET | 32 seconds | 8 sec |
Mono | 34 sec | 10 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 1 | Test number 2 |
.NET | 1.5 sec | - |
Mono | 2 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):
Platform | Mono | .Net Framework |
serializer | Test number 1 | Test number 2 | K | Test number 1 | Test number 2 | K |
String concatination | 600 | - | one | 250 | - | one |
newton JSON.NET | 2,000 | - | 3.4 | 1,500 | - | 6 |
JavaScriptSerializer | 5,000 | 4,000 | 8.3 / 6.7 | 1700 | 1700 | 6.8 |
JsonExSerializer | 34,000 | 10,000 | 56.7 / 16.7 | 4,000 | 3,500 | 16/14 |
Fluent json | 34,000 | 10,000 | 56.7 / 16.7 | 32,000 | 8,000 | 128/32 |
DataContractJsonSerializer | 34,000 | 34,000 | 56.7 / 56.7 | 1,500 | 1,500 | 6 |
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 ):
Platform | Mono | .Net Framework |
Serializer | Test number 1 | Test number 2 | K | Test number 1 | Test number 2 | K |
new StringBuilder (400) | 550 | - | 0.9 | 270 | - | one |
ServiceStack | 1,300 | - | 2.2 | 1200 | - | 4.8 |
Fast Json | 2,600 | - | 4.3 | 1200 | - | 4.8 |
Jayrock | 8,200 | - | 13.7 | 9200 | - | 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.