Under the cover of i4o

I did some per­for­mance opti­miza­tion work a lit­tle while back, and one of the changes which yield­ed a sig­nif­i­cant result was when I migrat­ed some serv­er side com­po­nents (which are CPU inten­sive and per­forms a large num­ber of loops) from using ADO.NET DataSets to using POCOs (plain old CLR object).

The loop­ing was then done using LINQ to Objects, and I dis­cov­ered a nice lit­tle exten­sion to LINQ called i4o — which stands for Index for Objects — to help make the loops faster. How­ev­er, I wasn’t able to observe any dif­fer­ence in per­for­mance, which con­tra­dicts with the find­ings on Aaron’s Tech­nol­o­gy Mus­ing

Dig­ging a lit­tle deep­er into the i4o source code (admit­ted­ly I didn’t do this myself, cred­it to Mike Bark­er for doing this!), it turns out that there are a num­ber of draw­backs in i4o which aren’t imme­di­ate­ly obvi­ous or men­tioned any­where in the doc­u­men­ta­tion. The biggest prob­lem for us was that it only sup­ports equal­i­ty com­par­i­son, which means it would sim­ply ignore the index you have on the MatchID prop­er­ty if you try to run this query:

var result = from m in Matches where m.MatchID >= 1 select m;

but it’ll use the index on MatchID if you run this query instead:

var result = from m in Matches where m.MatchID == 1 select m;

The con­clu­sion?

i4o is an awe­some tool that can tur­bo boost your LINQ query, but ONLY put indices on prop­er­ties which you will be doing equal­i­ty com­par­i­son in your queries oth­er­wise you’ll just be wast­ing some mem­o­ry space hold­ing indices which would be used at all.