Quite some time ago I was asked to cover a C# devel­oper inter­view for one of my neigh­bour­ing teams, and on the sheet of ques­tions the orig­i­nal inter­viewer wanted me to ask was this question:

Q. Why should you NEVER use delegates?

I thought: “Well, at least I can rule myself out for the role!”

To my mind, if using del­e­gates com­pli­cates your code or make it less readable/maintainable then you shouldn’t use it, but to say NEVER to using del­e­gates? It just doesn’t make sense…

Puz­zled, I asked: “Why not?”

Because it’s an order of mag­ni­tude slower than using methods”

Sounds like he’s had his fin­gers burnt in the past, but still, it goes against every­thing I have expe­ri­enced with using delegates..

At least it is in the case of .Net 1.1″

Ahh, a lit­tle more con­text makes it that much more believ­able! But mind you, this was 2009 and .Net 3.5 had been out and surely what­ever per­for­mance issue with del­e­gates would have been fixed long along…

The Test

So, some two years later, I decided to put together a quick test to see if there is any dif­fer­ence in per­for­mance between invok­ing a del­e­gate and a method in C# 4. The test is sim­ple, given an empty del­e­gate and method (see below), invok­ing each 10000 times in a row, which would take longer?

   1: Action MyDelegate = () => {};

   2:  

   3: void MyMethod() {}

It’s worth not­ing that the test code is run in a debug, non-optimized (so no com­piler in-lining) build.

The Result

Some­what sur­pris­ingly, invok­ing del­e­gates proved to be faster, aver­ag­ing 269 ticks over 5 runs, where as invok­ing meth­ods took an aver­age of 365 ticks!

Share

For a while now I’ve been won­der­ing why C#‘s sup­port for covari­ance does not cover value types, both in nor­mal array covari­ance and covari­ance in the generic para­me­ter intro­duced in C# 4:

   1: void Main()

   2: {

   3:     int i = 0;

   4:     string str = "hello world";

   5:     

   6:     TestMethod(i);       // legal

   7:     TestMethod(str);     // legal

   8:     TestMethod2(Enumerable.Empty<int>());           // illegal

   9:     TestMethod2(Enumerable.Empty<string>());        // legal

  10:     

  11:     Console.WriteLine(i is object);                 // true

  12:     Console.WriteLine(new int[0] is object[]);      // false

  13:     Console.WriteLine(new string[0] is object[]);   // true

  14:     Console.WriteLine(new uint[0] is int[]);        // false

  15: }

  16:  

  17: public void TestMethod(object obj)

  18: {

  19:     Console.WriteLine(obj);

  20: }

  21:  

  22: public void TestMethod2(IEnumerable<object> objs)

  23: {

  24:     Console.WriteLine(objs.Count());

  25: }

Until I stum­bled upon this old post by Eric Lip­pert on the topic of array covari­ance, which essen­tially points to a dis­agree­ment in the C# and CLI spec­i­fi­ca­tion on the rule of array covariance:

CLI

if X is assign­ment com­pat­i­ble with Y then X[] is assign­ment com­pat­i­ble with Y[]

C#

if X is a ref­er­ence type implic­itly con­vert­ible to ref­er­ence type Y then X[] is implic­itly con­vert­ible to Y[]

Whilst this doesn’t directly point to the gener­ics case with IEnumerable<out T>, one would expect they are one and the same, oth­er­wise you end up with dif­fer­ent rules for int[] and IEnumerable<int> where (new int[0] is IEnumerable<int>) == true.. now that would be weird!

Ref­er­ences:

Eric Lip­pert – Why is covari­ance of value-typed arrays inconsistent?

Ques­tion on Stack­Over­flow – why does my C# array lose type sign infor­ma­tion when cast to object?

Share

The other day I had an inter­est­ing obser­va­tion on the optional para­me­ters in C# 4, whereby if you spec­ify a para­me­ter as optional on an inter­face you don’t actu­ally have to make that para­me­ter optional on any imple­ment­ing class:

   1: public interface MyInterface

   2: {

   3:     void TestMethod(bool flag=false);

   4: }

   5:

   6: public class MyClass : MyInterface

   7: {

   8:     public void TestMethod(bool flag)

   9:     {

  10:         Console.WriteLine(flag);

  11:     }

  12: }

Which means you won’t be able to use the imple­ment­ing class and the inter­face interchangeably:

   1: var obj = new MyClass();

   2: obj.TestMethod(); // compiler error

   3:

   4: var obj2 = new MyClass() as MyInterface;

   5: obj2.TestMethod(); // prints false

Nat­u­rally, this bags the ques­tion of why the com­piler doesn’t enforce the imple­men­ta­tion to match the default value spec­i­fied by the contract?

Luck­ily, my sub­se­quent ques­tion on SO was answered by Eric Lip­pert from the C# com­piler team, not to waste time and effort repeat­ing what’s already been said, check out his answer and it’s clear to see the ratio­nale here and why it would be imprac­ti­cal and incon­ve­nient should the com­piler does it differently.

Ref­er­ences:

My ques­tion on StackOverflow

Arti­cle on pos­i­tives and pit­falls of using optional parameters

Share

Hav­ing spent quite a bit of time cod­ing in F# recently I have thor­oughly enjoyed the expe­ri­ence of cod­ing in a func­tional style and come to really like the fact you can do so much with so lit­tle code.

One of the counter-claims against F# has always been the con­cerns over per­for­mance in the most per­for­mance crit­i­cal appli­ca­tions, and with that in mind I decided to do a lit­tle exper­i­ment of my own using C# (LINQ & PLINQ) and F# to gen­er­ate all the prime num­bers under a given max value.

The LINQ and PLINQ meth­ods in C# look some­thing like this:

private static void DoCalcSequentially(int max)
{
    var numbers = Enumerable.Range(3, max-3);
    var query =
        numbers
            .Where(n => Enumerable.Range(2, (int)Math.Sqrt(n))
            .All(i => n % i != 0));
    query.ToArray();
}

private static void DoCalcInParallel(int max)
{
    var numbers = Enumerable.Range(3, max-3);
    var parallelQuery =
        numbers
            .AsParallel()
            .Where(n => Enumerable.Range(2, (int)Math.Sqrt(n))
            .All(i => n % i != 0));
    parallelQuery.ToArray();
}

The F# ver­sion on the other hand uses the fairly opti­mized algo­rithm I had been using in most of my project euler solutions:

let mutable primeNumbers = [2]

// generate all prime numbers under <= this max
let getPrimes max =
    // only check the prime numbers which are <= the square root of the number n
    let hasDivisor n =
        primeNumbers
        |> Seq.takeWhile (fun n' -> n' <= int(sqrt(double(n))))
        |> Seq.exists (fun n' -> n % n' = 0)

    // only check odd numbers <= max
    let potentialPrimes = Seq.unfold (fun n -> if n > max then None else Some(n, n+2)) 3
    // populate the prime numbers list
    for n in potentialPrimes do if not(hasDivisor n) then primeNumbers <- primeNumbers @ [n]

    primeNumbers

Here’s the aver­age exe­cu­tion time in mil­lisec­onds for each of these meth­ods over 3 runs for max = 1000, 10000, 100000, 1000000:

image

Have to admit this doesn’t make for a very com­fort­able reading…on aver­age the F# ver­sion, despite being opti­mized, runs over 3 – 6 times as long as the stan­dard LINQ ver­sion! The PLINQ ver­sion on the other hand, is slower in com­par­i­son to the stan­dard LINQ ver­sion when the set of data is small as the over­head of par­ti­tion­ing, col­lat­ing and coor­di­nat­ing the extra threads actu­ally slows things down, but on a larger dataset the ben­e­fit of par­al­lel pro­cess­ing starts to shine through.

UPDATE 13/11/2010:

Thanks for Jaen’s com­ment, the cause for the F# ver­sion of the code to be much slower is because of this line:

primeNumbers <- primeNumbers @ [n]

because a new list is con­structed every time and all ele­ments from the pre­vi­ous list copied over.

Unfor­tu­nately, there’s no way to add an ele­ment to an exist­ing List or Array in F# with­out get­ting a new list back (at least I don’t know of a way to do this), so to get around this per­for­mance hand­i­cap the eas­i­est way is to make the prime num­bers list a generic List instead (yup, luck­ily you are free to use CLR types in F#):

open System.Collections.Generic

// initialize the prime numbers list with 2
let mutable primeNumbers = new List<int>()
primeNumbers.Add(2)

// as before
...

    // populate the prime numbers list
    for n in potentialPrimes do if not(hasDivisor n) then primeNumbers.Add(n)

    primeNumbers

With this change, the per­for­mance of the F# code is now com­pa­ra­ble to that of the stan­dard LINQ version.

Share

Occa­sion­ally you might want to make the value of a sta­tic or instance field local to a thread (i.e. each thread holds an inde­pen­dent copy of the field), what you need in this case, is a thread-local stor­age.

In C#, there are mainly two ways to do this.

Thread­Sta­tic

You can mark a field with the Thread­Sta­tic attribute:

[ThreadStatic]
public static int _x;
…
Enumerable.Range(1, 10).Select(i => new Thread(() => Console.WriteLine(_x++))).ToList()
          .ForEach(t => t.Start()); // prints 0 ten times

Whilst this is the eas­i­est way to imple­ment thread-local stor­age in C# it’s impor­tant to under­stand the lim­i­ta­tions here:

  • the Thread­Sta­tic attribute doesn’t work with instance fields, it com­piles and runs but does nothing..
[ThreadStatic]
public int _x;
…
Enumerable.Range(1, 10).Select(i => new Thread(() => Console.WriteLine(_x++))).ToList()
          .ForEach(t => t.Start()); // prints 0, 1, 2, … 9
  • field always start with the default value
[ThreadStatic]
public static int _x = 1;
…
Enumerable.Range(1, 10).Select(i => new Thread(() => Console.WriteLine(_x++))).ToList()
          .ForEach(t => t.Start()); // prints 0 ten times

ThreadLocal<T>

C#  4 has intro­duced a new class specif­i­cally for the thread-local stor­age of data – the ThreadLocal<T> class:

private readonly ThreadLocal<int> _localX = new ThreadLocal<int>(() => 1);
…
Enumerable.Range(1, 10).Select(i => new Thread(() => Console.WriteLine(_localX++))).ToList()
          .ForEach(t => t.Start()); // prints 1 ten times

There are some bonuses to using the ThreadLocal<T> class:

  • val­ues are lazily eval­u­ated, the fac­tory func­tion eval­u­ates on the first call for each thread
  • you have more con­trol over the ini­tial­iza­tion of the field and is able to ini­tial­ize the field with a non-default value

Sum­mary

As you can see, using ThreadLocal<T> has some clear advan­tages over Thread­Sta­tic, though using 4.0 only fea­tures like ThreadLocal<T> means you have to tar­get your project at the .Net 4 frame­work and is there­fore not back­ward com­pat­i­ble with pre­vi­ous ver­sions of the framework.

It’s also worth not­ing that besides ThreadLocal<T> and Thread­Sta­tic you can also use Thread.GetData and Thread.SetData to fetch and store thread spe­cific data from and to a named Local­Data­S­toreS­lot though this is usu­ally cumbersome…

Share