One of a new wave of buzz­words that have been made pop­u­lar by the emerg­ing breed of Ruby/Scala devel­op­ers, low cer­e­mony is usu­ally used to describe web frame­works – if a frame­work is “low cer­e­mony” then the amount of setup/configuration it requires is min­i­mal and the cen­tral idea is that it will stay out of your work and lets you focus on your code.

Share

Note: don’t for­get to check out the Bench­marks page to see the lat­est round up of binary and JSON serializers.

When work­ing with the Bina­ry­For­mat­ter class fre­quently, one of the things you notice is that it is really damn inef­fi­cient… both in terms of speed as well as the pay­load (the size of the seri­al­ized byte array).

Google’s Pro­to­col Buffers for­mat is designed to be super fast and min­i­mizes the pay­load by requir­ing a seri­al­iz­able object to define ahead of time the order in which its properties/fields should be serialized/deserialized in, doing so removes the need for all sorts of meta­data that tra­di­tion­ally need to be encoded along with the actual data.

Marc Grav­ell (of Stack­Over­flow fame!) has a .Net imple­men­ta­tion called ‘protobuf-net’, and is said to totally kick ass! As with most per­for­mance related top­ics, it’s hugely intrigu­ing to me so I decided to put it to test myself :-)

Assumptions/Conditions of tests

  1. code is com­piled in release mode, with opti­miza­tion option turned on
  2. 5 runs of the same test is per­formed, with the top and bot­tom results excluded, the remain­ing three results is then averaged
  3. 100,000 iden­ti­cal instances of type SimpleObject(see below) is seri­al­ized and deserialized
  4. serialization/deserializatoin of the objects hap­pen sequen­tially in a loop (no concurrency)

image

Results

Unsur­pris­ingly, the protobuf-net seri­al­izer wins hands-down in all three cat­e­gories, as you can see from the table below it is a stag­ger­ing 12x faster than Bina­ry­For­mat­ter when it comes to seri­al­iza­tion, with a pay­load size less than 15th of its counterpart’s.

One curi­ous obser­va­tion about the pay­load size is that, when I used a Bina­ry­Writer to sim­ply write every prop­erty into the out­put stream with­out any meta­data, what I got back should be the min­i­mum pay­load size with­out com­pres­sion, and yet the protobuf-net seri­al­izer still man­ages to beat that!

image

image

image

Bina­ry­For­mat­ter with ISerializable

I also tested the Bina­ry­For­mat­ter with a class that imple­ments the ISe­ri­al­iz­able inter­face (see below) because oth­ers had sug­gested in the past that you are likely to get a notice­able per­for­mance boost if you imple­ment the ISe­ri­al­iz­able inter­face your­self. The belief is that it will per­form much bet­ter as it removes the reliance on reflec­tion which can be detri­men­tal to the per­for­mance of your code when used excessively.

How­ever, based on the tests I have done, this does not seem to be the case, the slightly bet­ter seri­al­iza­tion speed is far from con­clu­sive and is off­set by a slightly slower dese­ri­al­iza­tion speed..

image

Source code

If you’re inter­ested in run­ning the tests your­self, you can find the source code here, it uses my Sim­ple­SpeedTester frame­work to orches­trate the test runs but you should be able to get the gist of it fairly easily.

UPDATE 2011/08/24:

As I men­tioned in the post, protobuf-net man­aged to pro­duce a smaller pay­load than what is required to hold all the prop­erty val­ues of the test object with­out any meta.

I posted this ques­tion on SO, and as Marc said in his answer the smaller pay­load is achieved through the use of varint and zigzag encod­ing, read more about them here.

Share

Since I do a fair bit of per­for­mance tests on ran­dom things that pique my inter­est, it’s only nat­ural that I should make the task of car­ry­ing out these tests eas­ier for myself, so over the week­end I put together a sim­ple, no frills frame­work to do just that!

The Sim­ple­SpeedTester project is intended to make it eas­ier to:

  • time the exe­cu­tion of some code
  • orches­trate mul­ti­ple runs of the same test
  • col­late the exe­cu­tion time of the test runs
  • pro­vide an easy way to obtain sum­mary for the tests

What it’s not

It’s not a pro­filer! It doesn’t tell you which line of your code is tak­ing what per­cent­age of your CPU time or how much mem­ory is used where. It’s intended for one thing and one thing only – help you speed test a spe­cific piece of code/method over mul­ti­ple runs, col­late the results and work out the aver­age for you so you don’t have to.

Get­ting Started

To get started, down­load the bina­ries here, ref­er­ence the SimpleSpeedTester.dll in your project, and all you need is one line of code to sched­ule a test to be run mul­ti­ple times and get a sum­mary of the test runs:

   1: // initialize a new test group

   2: var testGroup = new TestGroup("Example2");

   3:  

   4: // PlanAndExecute executes the Action delegate 5 times and returns the result summary

   5: var testResultSummary = testGroup.PlanAndExecute("Test1", () => { }, 5);

   6:  

   7: Console.WriteLine(testResultSummary);

   8: /* prints out something along the line of

   9:  *

  10:  * Test Group [Example2], Test [Test1] results summary:

  11:  * Successes   [5]

  12:  * Failures    [0] 

  13:  * Average Exec Time [...] milliseconds

  14:  *

  15:  */

And you’re done! Easy, right? ;-)

I’ve included a cou­ple more exam­ples here cov­er­ing the most com­mon use cases, more will be added as I add more functionalities.

So what are you wait­ing for? Go on, down­load it and play around with it, let me know what you think, any con­struc­tive sug­ges­tions are very welcomed!

Share

Do you fancy a job mak­ing social games using the lat­est cutting-edge tech­nolo­gies? If your answer is yes then you are in luck, we’re look­ing to hire a C# devel­oper to join our server devel­op­ment team and help make us one of the lead­ing play­ers in the social gam­ing space.

Who are we?

We are IWI, a young, small, and dynamic social games stu­dio based in the heart of London’s west end. We focus on devel­op­ing social games across mul­ti­ple plat­forms such as Face­book, Hi5 and iOS.

What are we look­ing for?

You need to be an excel­lent team player and pos­sess excel­lent knowl­edge of C# and WCF, knowledge/experience of cloud plat­forms such as Ama­zon Web Ser­vices or Microsoft Azure will be desir­able but not essential.

We’re pas­sion­ate about tech­nol­ogy and would love to work with oth­ers who share our pas­sion, if you have a par­tic­u­lar inter­est in some tech­nol­ogy, or have inter­est­ing hobby projects, be it at home or hosted on Code­Plex, GitHub, etc. we cer­tainly would like to hear about them!

What do we offer?

You will have the chance to oper­ate within a small but ded­i­cated group of tal­ented devel­op­ers who are keen to work with cut­ting edge, new tech­nolo­gies. You will be able to make a mean­ing­ful con­tri­bu­tion on a day-to-day basis, and have the oppor­tu­nity to tackle scalability/performance chal­lenges sel­dom seen in other industries.

We uti­lize Ama­zon Web Ser­vices heav­ily and use its many ser­vices to build mas­sively scal­able and dis­trib­uted server solu­tions. Our cur­rent stack and toolset includes C# 4, WCF, EC2, Sim­pleDB (NoSql Data­base), RDS (man­aged MySql), Post­Sharp (AOP), Mem­base, an inter­est in at least a few of these will be a plus too.

Where to go next?

If you’re inter­ested in what we have to offer, then send your CV and Cover Let­ter to jobs@iwi.com.

Share

NOTE: For an updated set of bench­marks, see the Bench­marks page.

For those of you who have worked with JSON data in .Net you should be famil­iar with the Dat­a­Con­trac­tJ­son­Se­ri­al­izer class and the JavaScript­Se­ri­al­izer class already. Both allow you to serialize/deserialize an object to and from a piece of string in JSON for­mat, though there are some notable dif­fer­ences.

Besides these two BCL (base class library) JSON seri­al­iz­ers, there are pop­u­lar third-party offer­ing such as Json.Net and a rel­a­tively newer ServiceStack.Text which also offers its own seri­al­iza­tion for­mat called JSV (JSONCSV).

It is claimed that ServiceStack.Text’s JSON seri­al­izer is 3x faster than Json.Net and 3.6x faster than the BCL JSON seri­al­iz­ers! So, nat­u­rally, I had to test it out for myself and here’s what I found.

Assumptions/Conditions of tests

  1. code is com­piled in release mode, with opti­miza­tion options turned on
  2. 5 runs of the same test is per­formed, with the top and bot­tom results excluded, the remain­ing three results is then averaged
  3. 100,000 instances of type Sim­pleOb­ject (see below) is cre­ated, each with a dif­fer­ent ID and Name, and then given to the seri­al­iz­ers to seri­al­ize and deserialize
  4. serialization/deserialization of the objects hap­pen sequen­tially in a loop (no concurrency)
 1: [DataContract]
 2: public class SimpleObject
 3: {
 4:     [DataMember]
 5:     public int Id { get; set; }
 6:
 7:     [DataMember]
 8:     public string Name { get; set; }
 9: }

Results

With these assump­tions in mind, here are the aver­age times (in mil­lisec­onds) I recorded for seri­al­iza­tion and dese­ri­al­iza­tion using each of five JSON seri­al­iz­ers I tested:

image

image

Look­ing at these data, it would seem the ServiceStack.Text.JsonSerializer class offers the best speed in both seri­al­iza­tion and dese­ri­al­iza­tion cases, how­ever the gains are much more mod­est than those adver­tised in the case of seri­al­iza­tion. How­ever, it really comes into its own when it comes to dese­ri­al­iza­tion and the speed gains are quite impres­sive indeed!

Update 2011/09/12:

Turns out I had a typo in my per­for­mance test code and I was using Json.Net for the seri­al­iza­tion test for Sim­ple­J­son, my bad, sorry folks… So I fixed the typo and ran the tests again and updated the data and graph above with the cor­rect data. As Pra­bir Shrestha pointed out, by enabled Reflection.Emit you’re able to get much bet­ter per­for­mance out of Sim­ple­J­son and the new test results reflect this as the Sim­ple­J­son test was run whilst Reflection.Emit was enabled.

Share