LINQ Expression Trees on the Compact Framework
A week ago, I was writing about the ability to use Mono’s System.Core to run C# 3 and LINQ applications on .net 2.
A few months ago, I was writing about the new LINQ provider that friends at db4o released. This LINQ provider uses LINQ expression trees to optimize LINQ queries, turning them into db4o’s native query language.
Today I’m going to write about a cute new hack from our friends at db4o.
If the 3.5 version of the Compact Framework comes with a System.Core, and a LINQ to objects implementation, it doesn’t contain the namespace System.Linq.Expressions, which is used by all optimized LINQ providers. What those fine folks did, was simply to take Mono’s implementation of this namespace. There was one issue with that approach. Expression Trees can be compiled at runtime, and that uses System.Reflection.Emit, that the Compact Framework doesn’t have.
A nice thing is that folks at Mainsoft contributed to Mono’s System.Core an expression interpreter, which allows you to use the full LINQ expression trees without using System.Reflection.Emit. They sent me the patches they have for the expression interpreter to make it pass the full test suite we have, so I’ll integrate it shortly.
And voilĂ , just by using Mono’s implementation of System.Core, and by hacking a little in it, to make it compile on the Compact Framework, they’ve been able to produce a new assembly, System.Linq.Expressions.dll. You just have to reference it in your Compact Framework project, and it will let you use LINQ expression trees, which allows you to write optimized LINQ providers for the Compact Framework.
Of course, this is completely open-source and licensed under the MIT/X11. For now, you can find the code in db4o’s repository, but I’ll backport the changes they did to the LINQ expression interpreter, so that people that want to use it can use our code base directly.
Congrats to you guys for making the finest choice in the third party code you ship!
C# 3 and LINQ on .net 2 6
My friend Patrick is wondering what’s the best way to use the type System.Collections.Generic.HashSet, in NDepend, that he wants to deploy on computers with only .net 2 installed.
Well it’s pretty simple, the best way to get it, is to get it from Mono. The code is licensed under the MIT/X11 license, allowing multiple usages.
And that’s not all. If you’re dying to use C#3 or LINQ to objects in your application, but that you want to be able to release on .net 2 only, you can simply compile and ship Mono’s implementation of System.Core. Microsoft’s C# compiler, csc 3.5, won’t have any issue using it, et voilĂ , you’ll get an application using LINQ or C#3, and deployable on .net 2.
Mono’s implementation of System.Core is available in SVN here.
Cecil performance issues 2
At the beginning, Cecil was written to be an assembly manipulation library. The initial goal was to be able to read assemblies without loading them in an AppDomain, and also, to expose more that what .net 1.1 provided.
I implemented the writing parts of Cecil during my first Summer of Code, and barely touched it after, at it turns out it was working.
But this summer, two great hackers, Jeroen, author or IKVM, and Rolf, our VB 8 compiler author, decided that they gave enough blood and sweat to work around System.Reflection.Emit issues, and prototyped a version of their project based on Cecil instead.
If Rolf decided to go the full Cecil way, and replaced the usage of System.Reflection and System.Reflection.Emit (his branch is available), Jeroen decided to write a layer on top of Cecil that mimics the System.Reflection.Emit API.
Both wrote a sum-up about their findings, here for Jeroen, and there for Rolf. And both came to the conclusion that Cecil performs a lot less well that System.Reflection.Emit, both in terms of speed and memory consumption.
Rolf also uses the delay loading branch of Cecil, created by Mainsoft for their CIL to Java bytecode translator.
So the point is that Cecil uses too much memory, and is not fast enough in those scenarios, while it performs better in the reading only or reading + manipulating.
The good news is that, thanks to those hackers, we have now two amazing test cases to work on and to optimize. I’ve also started a few weeks ago, as a night hack, a refactoring of Cecil, that removes the intermediate structures that the current version of Cecil uses to read and write assemblies. If that makes reading and writing a little bit more complicated, it should also save a lot of memory.
And who knows, maybe one day, when Cecil will be optimized properly, and that the SRE on top of Cecil layer will be sufficient, it will require only a couple of changes to base mcs on Cecil.
Anyway, kudos to those hackers, let see what I can do to catch up.
We’ll let you know!




