Latest Event Updates

protobuf-net v2 performance test

Posted on Updated on

This is a continuation from my previous post of Run time initialisation of protobuf-net v2 without annotation

I listed couple of ways to use protobuf-net v2:

  1. annotation on the class (ProtoContractAttribute) and property (ProtoMemberAttribute)
  2. annotation only on the class (ProtoContractAttribute) with ImplicitFields named parameter
  3. run time registration using the default model (RuntimeTypeModel.Default)
  4. run time registration with separate type model which supports run time compilation (from the method description -> Fully compiles the current model into a static-compiled serialization dll)
  5. precompiled serializer (this is not really a different method, but a further optimisation to the 1st and 2nd options above)

Based on the list above, I created some performance tests using a class defined with 150+ properties (mixed with string, custom classes) to make it closer to real life entity that I have in the project.
And below is the statistics produced by the test for different collection sizes, ordered by the most “efficient” ones to regular binary serialization for comparison purpose.

Conclusions:

  • Performance : Precompiled serializer seems to be the notable performant option, although as you can see below, the other protobuf options are not very far off from one to another as well
  • Size : ImplicitFields seems to be the smallest in size, although it’s not far off to other options, although the run time compiled model option seems to be on the higher end.

Please note that this benchmark below is purely for my curiosity purpose, please do NOT refer this as a guidelines for any of your application.
The main reason why I’m saying the above is because I actually found somewhat different statistics when I tried to run this on the real class/model being used in my project.
The performance is somewhat as below between, however the size was the quite surprising factor where the memory size for the run time registration was 50% higher than the annotation option hence we ended up sticking up with the full annotation option as size is a very important factor as we need to send the data through the wire hence any significant size increase will introduce latency.
So again, moral of the story, please ALWAYS run a benchmark using your real project before jumping into any conclusion.
Attached the sample project again below for reference as usual.

Sample Project


-------------------------------
TestProtobufPreCompiledTypeModel
100 items, Size: 238905, Completed: 30 ms, Serialization: 6 ms, Deserialization: 13 ms
1000 items, Size: 2389006, Completed: 378 ms, Serialization: 69 ms, Deserialization: 161 ms
10000 items, Size: 23890006, Completed: 4195 ms, Serialization: 675 ms, Deserialization: 1806 ms
-------------------------------
TestProtobufRuntimeRegistrationWithCompiledTypeModel
100 items, Size: 273805, Completed: 42 ms, Serialization: 7 ms, Deserialization: 24 ms
1000 items, Size: 2738006, Completed: 424 ms, Serialization: 76 ms, Deserialization: 191 ms
10000 items, Size: 27380006, Completed: 4634 ms, Serialization: 762 ms, Deserialization: 2151 ms
-------------------------------
TestProtobufRuntimeRegistration
100 items, Size: 238000, Completed: 35 ms, Serialization: 8 ms, Deserialization: 16 ms
1000 items, Size: 2380000, Completed: 415 ms, Serialization: 78 ms, Deserialization: 173 ms
10000 items, Size: 23800000, Completed: 4692 ms, Serialization: 785 ms, Deserialization: 2182 ms
-------------------------------------
TestProtobufImplicitAnnotatedEntities
100 items, Size: 237700, Completed: 35 ms, Serialization: 7 ms, Deserialization: 17 ms
1000 items, Size: 2377000, Completed: 429 ms, Serialization: 78 ms, Deserialization: 201 ms
10000 items, Size: 23770000, Completed: 4799 ms, Serialization: 796 ms, Deserialization: 2207 ms
----------------------------------
TestProtobufFullyAnnotatedEntities
100 items, Size: 238900, Completed: 33 ms, Serialization: 8 ms, Deserialization: 14 ms
1000 items, Size: 2389000, Completed: 423 ms, Serialization: 79 ms, Deserialization: 166 ms
10000 items, Size: 23890000, Completed: 4734 ms, Serialization: 782 ms, Deserialization: 2243 ms
------------------
TestBinaryEntities
100 items, Size: 426909, Completed: 82 ms, Serialization: 30 ms, Deserialization: 36 ms
1000 items, Size: 4183509, Completed: 1537 ms, Serialization: 384 ms, Deserialization: 997 ms
10000 items, Size: 41749512, Completed: 89895 ms, Serialization: 4173 ms, Deserialization: 83900 ms

Advertisements

Run time initialisation of protobuf-net v2 without annotation

Posted on

I have been using protobuf-net for the project at office but it’s only implemented for a limited number of entities (or business objects). We’re now trying to see how to implement this to the whole entities that we’re sending back n forth between the UI and the back end.

As we’re currently using a code generation “tool” to produce the code, we’re thinking to incorporate the annotation/attribute into the generated class/property code, however due to some not really technical reason, this is a bit complicated to achieve.

I thought of checking the site again to get some idea and I came across to this statement “allow use without attributes if you wish” on the page.

Then I tried to dig out more on the SO and found some more good leads on this. Apparently it’s very much possible to perform “registration” during run time mode which allows us NOT to use any annotation on the entities.

So thanks to the pointers, there are 2 alternatives for this:
1. With very minimal annotation on the class level

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)] // only required on the class level
class PersonEntity
{
   public string FirstName { get; set; }
   public string LastName { get; set; }
}

2. Without any annotation (using RuntimeTypeModel)

static void InitializeProtobufRunTime()
{
    var assembly = Assembly.GetAssembly(typeof(PlainEntities.PersonEntity));
    var types = assembly.GetTypes();
    foreach (var t in types.Where(x => x.Namespace.Contains("PlainEntities")))
    {
        Console.WriteLine("Processing {0}", t.FullName);
        var meta = RuntimeTypeModel.Default.Add(t, false);
        var index = 1;

        // find any derived class for the entity
        foreach (var d in types.Where(x => x.IsSubclassOf(t)))
        {
            var i = index++;
            Console.WriteLine("\tSubtype: {0} - #{1}", d.Name, i);
            meta.AddSubType(i, d);
        }

        // then add the properties
        foreach (var p in t.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly).Where(x => x.GetSetMethod() != null))
        {
            var i = index++;
            Console.WriteLine("\tProperty: {0} - #{1}", p.Name, i);
            meta.AddField(i, p.Name);
        }
    }
}

And both the above works quite well without any performance differences.


------------------
TestBinaryEntities
------------------
Process: 100000 items, MemorySize: 7400705, Completed in: 3877 ms, Serialization took: 676 ms, Deserialization took: 2948 ms

----------------------------------
TestProtobufFullyAnnotatedEntities
----------------------------------
Process: 100000 items, MemorySize: 3983490, Completed in: 682 ms, Serialization took: 164 ms, Deserialization took: 253 ms

-------------------------------------
TestProtobufImplicitAnnotatedEntities
-------------------------------------
Process: 100000 items, MemorySize: 3983490, Completed in: 595 ms, Serialization took: 104 ms, Deserialization took: 210 ms

-------------------------------
TestProtobufRuntimeRegistration
-------------------------------
Processing ProtobufTestConsole.PlainEntities.BaseEntity
Subtype: PersonEntity - #1
Property: Id - #2
Property: Gender - #3
Processing ProtobufTestConsole.PlainEntities.PersonEntity
Property: FirstName - #1
Property: LastName - #2
Property: Age - #3
Process: 100000 items, MemorySize: 4083490, Completed in: 646 ms, Serialization took: 113 ms, Deserialization took: 232 ms

Looking forward to get this in :)

Also attached the sample project for reference

Sample Project

Why Task Parallel Library (TPL) = Great stuffs

Posted on

I just came back to office today from a short staycation and while going through the email back logs, I saw an email from a colleague asking for my practical experience with the Task Parallel Library (TPL) so far.

I’m quite delighted to share some with him and thought of just dropping some to here as well ;)

Practical usages:

  • Parallel data retrieval from different sources
    This has saved significant amount of time, e.g. we have 3 data retrievals, the 1st takes 10 seconds, the 2nd takes 7 seconds and the 3rd takes 4 seconds, rather than 21 seconds sequentially, we can get all 3 results in 10 (max) now.
  • Parallel data submission with limited concurrency
    With long running processes, we need to be careful not to overload the back end services, so when TPL comes with Limited Concurrency Task Scheduler, this becomes a life saver and we can remove all the previous code complexities to achieve the same.

Summaries:

  • The Task has greatly simplified the developer’s code to be able to perform asynchronous operation which returns values where previously it’s not straight forward to achieve the same (e.g. creaging a wrapper using threadpool)
  • Out of the box / It comes with the .Net 4 (directly shipped by microsoft), this very much makes TPL available for us (developers) and the users (client) without worrying a separate component to download
  • More good stuffs are on the way with latest .Net 4.5 Framework

The downsides:

  • Potential parallelism -> good stuff + not too good stuff, good stuff -> we don’t need to worry, not too good stuff -> there are times that we want it to happen in parallel but it’s too clever not to do parallel in heavy usage especially in low spec machine (e.g. client machine is not as good as our developer PC)
  • Unit testing -> It’s not so easy to test our code if we start mixing TPL into our code, although it’s true that we should separate the logic bit from the concurrency, but in reality sometimes we end up with unnecessary code to make it testable. I do hope more improvements to come for this, there are many being discussed in stackoverflow

Generate Func by using Expression Trees

Posted on Updated on

I stumbled in a code change today which involved some value look-up in a dictionary based on some property name which is by convention (paramA + paramB + “property”).

So there was used to be a pre-calculated sum stored in the dictionary by a user control.

class SomeClass
{
    public Decimal DailyFunctionalAmount { get; set; }
    public Decimal MonthToDateFunctionalAmount { get; set; }
    ///..... have much more here
}

Decimal GetTotal(String fieldName, IDictionary<String, Decimal> lookups)
{
    // used to be as simple as getting the pre-calculated sum via dictionary (populated somewhere else by control)
    var totalByLookup = lookups[fieldName];
    return totalByLookup;
}

Now, I need to rely on the underlying data rows to calculate the sum.

var lists = new List<SomeClass> {
    new SomeClass { DailyFunctionalAmount = 10, MonthToDateFunctionalAmount = 100},
    new SomeClass { DailyFunctionalAmount = 10, MonthToDateFunctionalAmount = 100},
};

// I could not use the following code as this is compiled/pre-determined code where we actually need the selector in run-time based on the generated property name by convention
var totalByLinq = lists.Sum(r => r.DailyFunctionalAmount); 

Luckily, there is this expression trees which seems to be perfect for the job, rather than a nasty static function returning selector based on possible combinations for the property name by convention.

// returns -> dtoType => dtoType.propertyName
Func<SomeClass, Decimal> GetMyFunc(string propertyName)
{
    var dtoTypeParameter = Expression.Parameter(typeof(SomeClass), "dtoType");
    var dtoPropertySelector = Expression.Property(dtoTypeParameter, propertyName);
    var lamdaExpression = Expression.Lambda<Func<SomeClass, Decimal>>(dtoPropertySelector, new ParameterExpression[] { dtoTypeParameter });

    return lamdaExpression.Compile();
}

Decimal GetTotal(String fieldName, IEnumerable<SomeClass> lists)
{
    // solution - generate the func in run-time
    var runTimeSelector = GetMyFunc(fieldName);
    var totalByLinq = lists.Sum(runTimeSelector);
    return totalByLinq;
}

It’s surely world of possibilities with this expression trees ;)

Full source code below:

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        var lists = new List<SomeClass> {
            new SomeClass { DailyFunctionalAmount = 10, MonthToDateFunctionalAmount = 100},
            new SomeClass { DailyFunctionalAmount = 10, MonthToDateFunctionalAmount = 100},
        };

        var lookups = new Dictionary<String, Decimal>(); // stored with the property name as key in the dictionary and the sum as value
        lookups.Add("DailyFunctionalAmount", 20);
        lookups.Add("MonthToDateFunctionalAmount", 200);

        var dailyFunctionalFieldName = GetFieldName("Daily", "Functional");
        var monthToDateFunctionalFieldName = GetFieldName("MonthToDate", "Functional");

        // old way
        Assert.AreEqual(20, GetTotal(dailyFunctionalFieldName, lookups));
        Assert.AreEqual(200, GetTotal(monthToDateFunctionalFieldName, lookups));

        // new way 
        Assert.AreEqual(20, GetTotal(dailyFunctionalFieldName, lists));
        Assert.AreEqual(200, GetTotal(monthToDateFunctionalFieldName, lists));
    }

    Decimal GetTotal(String fieldName, IDictionary<String, Decimal> lookups)
    {
        // used to be as simple as getting the pre-calculated sum via dictionary (populated somewhere else by control)
        var totalByLookup = lookups[fieldName];
        return totalByLookup;
    }

    Decimal GetTotal(String fieldName, IEnumerable<SomeClass> lists)
    {
        // now it needs to be manually calculated from the list

        //var totalByLinq = lists.Sum(r => r.DailyFunctionalAmount); // but this is compiled/pre-determined code where we actually need the selector in run-time

        // solution - generate the func in run-time
        var runTimeSelector = GetMyFunc(fieldName);
        var totalByLinq = lists.Sum(runTimeSelector);
        return totalByLinq;
    }

    String GetFieldName(String periodic, String currency)
    {
        // the field name is generated by some convention [Daily/MonthToDate] + [Functional/Transaction] + "Amount"
        return periodic + currency + "Amount";
    }

    // returns -> dtoType => dtoType.propertyName
    Func<SomeClass, Decimal> GetMyFunc(string propertyName)
    {
        var dtoTypeParameter = Expression.Parameter(typeof(SomeClass), "dtoType");
        var dtoPropertySelector = Expression.Property(dtoTypeParameter, propertyName);
        var lamdaExpression = Expression.Lambda<Func<SomeClass, Decimal>>(dtoPropertySelector, new ParameterExpression[] { dtoTypeParameter });

        return lamdaExpression.Compile();
    }
}

class SomeClass
{
    public Decimal DailyFunctionalAmount { get; set; }
    public Decimal MonthToDateFunctionalAmount { get; set; }
    ///..... have much more here
}

Blending with Sample Data feature (Blend 4)

Posted on

Had a chance to play more with Blend 4 this week, have been eyeing on the Sample Data feature for a while but only had a chance to use it in practice now.

So imagine if you have defined the backing view model below

public class MainViewModel
{
	public MainViewModel()
	{
		// Insert code required on object creation below this point.
	}
	public IList<Person> Persons { get; set; }
}

public abstract class Person
{
	public String Name { get; set; }
	public Int32 Age { get; set; }
	public String Initials { get{ return "some initials"; } }
}

public class Male : Person
{
}

public class Female : Person
{
}

You can then open the view, on the top right panel, click on the Create Sample Data from Class option below

Choose the view model to generate the sample data, click Ok

Bam! the sample data file has been generated nicely below, and notice one thing, the read only Initials property can be “set” as well there :)


Before moving on to the next step, be sure to replace Person Type on the rows into either Male or Female.

Now, time to get into the view with the d:DataContext binding and data templates by Data Type for each Male and Female.

hhhmm… a little bit disappointing, isn’t it? all are seem to be in place, but why it’s displaying these weirds _.di12.NameSpace.Class rather than our expected data template result?
Now back to the xaml, add d:IsDesignTimeCreatable=”False” attribute on both data template elements, save, close and reopen the xaml again.

And there’s the shiny UI with some sample data in it :)

Notice that Blend sometimes doesn’t refresh the design view as soon as we make some changes on the data template (it works fine on non data template changes).
I only found that the effective way is to just close and reopen to see the changes effect, so if you’re editing something on the data template and it’s not reflecting, try to close and reopen it first :)

I found this sample data feature is very useful, how bout you?

Have also shared the sample project for grabs here.

Hope this helps :)

Fallen into the pit of overconfidence

Posted on Updated on

If someone had asked me yesterday whether I’m a professional, mature, seasoned developer. I would certainly replied “Indeed, I am!”. Well, fortunately, no one did, or else I can’t imagine meeting him/her again today after the pathetic thing below.

You see, I was working on a defect/bug yesterday, it was a pretty simple bug that I was happily to fix as it looks like a less than an hour job, so I did the fix below, got the test evidences and marked that defect as fixed, ready for promotion to the test environment.

private Boolean _someFlag;
private String _someOption;

private void Execute()
{
    //... some codes here

    // the following block of codes is the fix to resolve the defect/bug
    if (_someOption.Contains("something"))
    {
        _someFlag = true;
    }
    else
    {
        _someFlag = false;
    }

    //... some codes here
}

To my horror this morning, there’s a new defect being raised, complaining that there’s an error pop-up whenever the user tried to click on the execute button.

And quickly I realized that the error was coming from the modified code above. And to make things worst, the code above is in the base class of let say 10 UI forms and 3 of them are now not working/usable at all due to this new bug.

Now fixing this new bug is another simple task to do, but the thing that stayed on my mind till now is that when I wrote that fix yesterday, it actually came to my mind that I should be putting some unit tests on them, this new bug will definitely get captured if I were to write the unit tests (basic positive, negative, null tests). But nah, my overconfidence took over that this is a simple fix, nothing’s going to ever happen with this fix, everything will be running happily tomorrow, I should check this in ASAP and hurrah! one defect down.

So what are the consequences with that?

  1. Testing activities were blocked on for 3 of 10 UIs, where actually without the code fix, all were actually working fine, it’s just a minor dodgy state that was incorrect
  2. One more day was wasted to get the new fix promoted so the testing can be continued
  3. For having end users/testers to actually see this error message, it’s embarrassing the development team
  4. And in the end, this kind of error is truly embarrassing for a .Net programmer, with these years of experiences for sure :|
The following is an excerpt taken from Uncle Bob Martin‘s The Clean Coder book.

(hope you don’t mind, Uncle Bob, I’ll make sure that I write the book review when I’m done reading your book :))

As you mature in your profession, your error rate should rapidly decrease towards the asymptote of zero. It won’t ever get to zero, but it is your responsibility to get as close as possible to it.

Hit the nail on the head of what I was expected to do. So moral of the story, be humble, don’t ignore your inner voice, and believe in unit testing/TDD.

PS: Tony, if you actually read this, just know that today in my head, i kept imagining you’re telling me “See, I told you, Bembeng” :p

New CLR Profiler for .NET Framework 4

Posted on

We just found a memory leak (again) in our latest code base that we’re going to release to production next month, seems that we’re having this issue for every release :p i think it’s unavoidable considering the amount of changes that we’re making on the app for each release ;)

Now, when I tried to do the regular steps to investigate the root cause, the CLR Profiler was not responding when I clicked the Show Heap now button and eventually display the pop-up below.

Then realised that since we have just upgraded the application to use .Net 4.0, so there’s a chance that there’s a new CLR Profiler on the block for .Net 4.0, and turned out there is actually a new one available in MSDN. And it’s not surprising, considering that .Net 4.0 comes with a new CLR as well (click on the image below to go to the msdn website for more info)

After downloaded the new CLR Profiler 4, it looks like below, notice the new Attach Process and Detach Process buttons, those will be very useful as we always need to start the application in the previous version, sweet! :)

Now, it’s time to duck into the the heap :)