March 16, 2007

How you can have Ruby-style enumerations in C# 3.0

Well, I missed MVP Summit this year, so while fellow MVPs enjoying together in Redmond I'm playing with C# 3.0 at home. And I'm in the process of Ruby learning, so what I spotted immediately is the lack (correct me if I'm wrong) of Each() and Map() support in .NET 3.5 collections ...

What would be advantages of having Each() method instead of foreach loop?

  1. Syntactically foreach loop is a statement, while Each() method is expression. Expressions are usually simpler structurally than statements and more readable.
  2. foreach loop follows and encourages imperative programming style, Each()  - functional one.
  3. Clean and beautiful

So I put together some quick implementation of IEnumerable.Each(subroutine) and IEnumerable.EachIndex(subroutine) extension methods after Ruby's  each() and each_index().

IEnumerable.Each(subroutine) extension method calls given subroutine (just a function returning void) once for each element in the collection, passing that element as a parameter.

IEnumerable.EachIndex(subroutine) extension method does the same, but but passes the index of the element instead of the element itself.

With those two methods I can process collections in Ruby-style functional code style:

int[] squares = new int[10];
squares.EachIndex(i => squares[i] = i * i);
squares.Each(val => Console.WriteLine(val)); 

The implementation is suspiciously easy:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Test
{
       public static class MyIEnumerableExtensions
    {        
        public static void Each<TSource>(this IEnumerable<TSource> source, Action<TSource> action) 
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (action == null)
            {
                return;
            }
            foreach (TSource item in source)
            {
                action(item);
            }
        }

        public static void EachIndex<TSource>(this IEnumerable<TSource> source, Action<int> action)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (action == null)
            {
                return;
            }
            int i = 0;
            IEnumerator<TSource> enumerator = source.GetEnumerator();
            while (enumerator.MoveNext())
            {
                action(i++);
            }
        }        
    }
}
Cool. Now what about transforming collection elements, I mean Map()?

March 15, 2007

Fast clean way to check if an array contains particular element in C# 3.0

I just started coding some real application with C# 3.0 (this is my favorite way of learning things) and immediately I can say I love it. C# 3.0 is going to be the best C# version ever. For me personally C# 1.0 was "hey look, kinda Java for Windows", C# 2.0 was "finally generics" and ...
if (args.Contains("/help")) 
    PrintUsage();

That matches exactly Ruby include?() method:

PrintUsage() if args.include?("/help")

Alternatively you can use Any() extension method with lambda expression:

if (args.Any(arg => arg == "/help" || arg == "/?"))

"using System.Linq;" is all you need to turn this magic on.

I was wondering how fast extension methods are. So I put some quick benchmark code checking if a random data array contains some value using foreach loop, for loop, Contains() extension method and Any() extension method. The results I got were somehow surprising:

foreach loop search:            35 ms
for loop search:                28 ms
Contains() method search:       15 ms
Any() method search:            152 ms

Well, Any() method builds dynamic lambda expression in memory, so it's obviously the slowest one, but Contains() extension method somehow wins!

How come Contains() can beat almost twice in speed plain dumb for loop? I always new declarative style is the most optimization-friendly, but that was always kinda theory only.

Unfortunately I have no time to disassemble things, gotta go right now. Could be boxing or array boundaries checking or inlining. Can somebody shed some light into this? I'm including my benchmark code, chances are it's not fully correct. Run it in latest Visual Studio Orcas March CTP.

Anyway, it's good to know that really fast and the most elegant way to check if an array contains particular element in C# 3.0 seems to be using Contains() extension method.

using System;
using System.Diagnostics;
using System.Linq;

namespace Test
{
    class Program
    {        
        static void Main(string[] args)
        {
            int[] data = new int[10000000];
            //Fill in some random data
            Random rand = new Random();
            for (int i=0; i<data.Length; i++)
            {
                data[i] = rand.Next();
            }
            //Select some element for search
            int value = data[data.Length/2];

            //Warm up
            ContainsViaForEachLoop(data, value);
            ContainsViaForLoop(data, value);
            ContainsViaContainsExtMethod(data, value);
            ContainsViaAnyExtMethod(data, value);

            Stopwatch watch = new Stopwatch();
            watch.Start();
            if (ContainsViaForEachLoop(data, value))
            {
                watch.Stop();
                Console.WriteLine("foreach loop search:\t\t{0} ms", 
                    watch.ElapsedMilliseconds);
            }
            watch.Reset();            
            watch.Start();
            if (ContainsViaForLoop(data, value))
            {
                watch.Stop();
                Console.WriteLine("for loop search:\t\t{0} ms", 
                    watch.ElapsedMilliseconds);
            }
            watch.Reset();
            watch.Start();
            if (ContainsViaContainsExtMethod(data, value))
            {
                watch.Stop();
                Console.WriteLine("Contains() method search:\t{0} ms", 
                    watch.ElapsedMilliseconds);
            }
            watch.Reset();
            watch.Start();
            if (ContainsViaAnyExtMethod(data, value))
            {
                watch.Stop();
                Console.WriteLine("Any() method search:\t\t{0} ms", 
                    watch.ElapsedMilliseconds);
            }
        }

        public static bool ContainsViaForEachLoop(int[] data, int value)
        {
            foreach (int i in data)
            {
                if (i == value)
                {
                    return true;
                }
            }
            return false;
        }


        public static bool ContainsViaForLoop(int[] data, int value)
        {            
            for (int i=0; i<data.Length; i++)
            {
                if (data[i] == value)
                {
                    return true;
                }
            }
            return false;
        }

        public static bool ContainsViaContainsExtMethod(int[] data, int value)
        {
            return data.Contains(value);
        }

        public static bool ContainsViaAnyExtMethod(int[] data, int value)
        {
            return data.Any(i => i == value);
        }

    }
}

March 14, 2007

Google Mobile Proxy

This is not particularly new, but I didn't know about it before today and it did save my ass when I needed to browse non-mobile-friendly site on my phone really bad this morning. It's http://www.google.com/gwt/n - Google mobile proxy service. It allows to browse to any web site using your mobile ...

W3C wakes up before they lose control over HTML

After years wasted in XHTML and XForms development and before WHATWG totally taking over HTML, W3C woke up and restarted their HTML activity. Just about time. Yes, believe it or not, but after HTML 4.01, which was finished back in 1999, W3C did nothing to improve HTML. Meantime Google, Apple, Mozilla ...