Reimplementing LINQ to Objects: Part 42 – More optimization

A few parts ago, I jotted down a few thoughts on optimization. Three more topics on that general theme have occurred to me, one of them prompted by the comments. User-directed optimizations I mentioned last time that for micro-optimization purposes, we could derive a tiny benefit if there were operators which allowed us to turn off potential optimizations – effectively declare in the LINQ query that we believed the input sequence would never be an IList<T> or an ICollection<T>, so it wasn’t worth checking it. I still believe that level of optimization would be futile. However, going the other way … Continue reading Reimplementing LINQ to Objects: Part 42 – More optimization

Reimplementing LINQ to Objects: Part 41 – How query expressions work

Okay, first a quick plug. This won’t be in as much detail as chapter 11 of C# in Depth. If you want more, buy a copy. (Until Feb 1st, there’s 43% off it if you buy it from Manning with coupon code j2543.) Admittedly that chapter has to also explain all the basic operators rather than just query expression translations, but that’s a fair chunk of it. If you’re already familiar with query expressions, don’t expect to discover anything particularly insightful here. However, you might be interested in the cheat sheet at the end, in case you forget some of … Continue reading Reimplementing LINQ to Objects: Part 41 – How query expressions work

Reimplementing LINQ to Objects: Part 40 – Optimization

I’m not an expert in optimization, and most importantly I don’t have any real-world benchmarks to support this post, so please take it with a pinch of salt. That said, let’s dive into what optimizations are available in LINQ to Objects. What do we mean by optimization? Just as we think of refactoring as changing the internal structure of code without changing its externally visible behaviour, optimization is the art/craft/science/voodoo of changing the performance of code without changing its externally visible behaviour. Sort of. This requires two definitions: "performance" and "externally visible behaviour". Neither are as simple as they sound. … Continue reading Reimplementing LINQ to Objects: Part 40 – Optimization

Reimplementing LINQ to Objects: Part 39 – Comparing implementations

While implementing Edulinq, I only focused on two implementations: .NET 4.0 and Edulinq. However, I was aware that there were other implementations available, notably LinqBridge and the one which comes with Mono. Obviously it’s interesting to see how other implementations behave, so I’ve now made a few changes in order to make the test code run in these different environments. The test environments I’m using Mono 2.8 (I can’t remember the minor version number offhand) but I tend to think of it as "Mono 3.5" or "Mono 4.0" depending on which runtime I’m using and which base libraries I’m compiling … Continue reading Reimplementing LINQ to Objects: Part 39 – Comparing implementations

Reimplementing LINQ to Objects: Part 38 – What’s missing?

I mentioned before that the Zip operator was only introduced in .NET 4, so clearly there’s a little wiggle room for LINQ to Object’s query operators to grow in number. This post mentions some of the ones I think are most sorely lack – either because I’ve wanted them myself, or because I’ve seen folks on Stack Overflow want them for entirely reasonable use cases. There is an issue with respect to other LINQ providers, of course: as soon as some useful operators are available for LINQ to Objects, there will be people who want to apply them to LINQ … Continue reading Reimplementing LINQ to Objects: Part 38 – What’s missing?

Reimplementing LINQ to Objects: Part 37 – Guiding principles

Now that I’m "done" reimplementing LINQ to Objects – in that I’ve implemented all the methods in System.Linq.Enumerable – I wanted to write a few posts looking at the bigger picture. I’m not 100% sure of what this will consist of yet; I want to avoid this blog series continuing forever. However, I’m confident it will contain (in no particular order): This post: principles governing the behaviour of LINQ to Objects Missing operators: what else I’d have liked to see in Enumerable Optimization: where the .NET implementation could be further optimized, and why some obvious-sounding optimizations may be inappropriate How … Continue reading Reimplementing LINQ to Objects: Part 37 – Guiding principles

Gotcha around iterator blocks

This will be a short interlude from Edulinq, although as it will become obvious, it was in the process of writing the next Edulinq post that I made this discovery. It may be known about elsewhere, but it’s the first time I’d come across it – or rather, it’s the first time I’ve considered the impact of the compiler’s decisions in this area. Sequences and iterators This post is about details of iterator blocks and memory usage. It’s going to be quite important that you can easily follow exactly what I’m talking about, so I’m going to define a few … Continue reading Gotcha around iterator blocks

Reimplementing LINQ to Objects: Part 36 – AsEnumerable

Our last operator is the simplest of all. Really, really simple. What is it? AsEnumerable has a single signature: public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source) I can describe its behaviour pretty easily: it returns source. That’s all it does. There’s no argument validation, it doesn’t create another iterator. It just returns source. You may well be wondering what the point is… and it’s all about changing the compile-time type of the expression. I’m going to take about IQueryable<T> in another post (although probably not implement anything related to it) but hopefully you’re aware that it’s usually used for "out of process" … Continue reading Reimplementing LINQ to Objects: Part 36 – AsEnumerable

Reimplementing LINQ to Objects: Part 35 – Zip

Zip will be a familiar operator to any readers who use Python. It was introduced in .NET 4 – it’s not entirely clear why it wasn’t part of the first release of LINQ, to be honest. Perhaps no-one thought of it as a useful operator until it was too late in the release cycle, or perhaps implementing it in the other providers (e.g. LINQ to SQL) took too long. Eric Lippert blogged about it in 2009, and I find it interesting to note that aside from braces, layout and names we’ve got exactly the same code. (I read the post … Continue reading Reimplementing LINQ to Objects: Part 35 – Zip

Reimplementing LINQ to Objects: Part 34 – SequenceEqual

Nearly there now… What is it? SequenceEqual has two overloads – the obvious two given that we’re dealing with equality: public static bool SequenceEqual<TSource>(     this IEnumerable<TSource> first,     IEnumerable<TSource> second) public static bool SequenceEqual<TSource>(     this IEnumerable<TSource> first,     IEnumerable<TSource> second,     IEqualityComparer<TSource> comparer) The purpose of the operator is to determine if two sequences are equal; that is, if they consist of the same elements, in the same order. A custom equality comparer can be used to compare each individual pair of elements. Characteristics: The first and second parameters mustn’t be null, and are validated immediately. The comparer parameter can be null, … Continue reading Reimplementing LINQ to Objects: Part 34 – SequenceEqual