Debunking the LINQ “magic” myth again


I’ve blogged before about how LINQ-to-Objects, at it’s most basic, is just about building on top of enumerating, one at a time, over collections via MoveNext(). It wraps it up in a beautiful API, but it’s still generally crawling through collections. I wanted to give an example of this in more depth and how the C# team introduced some smart optimisations where possible.

And I’m sure that Jon Skeet’s fantastic EduLinq blog post goes into more detail than here, but anyway…

LINQ’s Any() vs Count()

I know a lot of people that tend to check for the existence of an empty collection with a collection.Count() == 0 check (or > 1 for non-empty ones). This obviously works, but there’s a better alternative i.e. collection.Any(). There are two reasons why you should favour this over Count: –

Readability

Compare the two examples below: –

  • if (employees.Count() > 0)
  • if (employees.Any())

The latter reads much better. The former invariably means that in your head you’re doing a “conversion” to “if there are any items”.

Performance

How does .Count() work? It simply iterates over every item in the collection to determine how many there are. In this situation, .Any() will be much, much quicker because it simply tests if there is at least one item in the collection i.e. does MoveNext() return true or not.

Decompiling LINQ

There’s one situation where the above is not true. If the underlying enumerable collection implements either version of ICollection, and you’re calling the parameter-less version of Count(), that extension method is smart enough to simply delegate to the already-calculated Count property. Again – this only applies to the parameter-less version! So for the version of Count that takes in a predicate, the first of the next two samples will generally be much quicker than the latter: –

  • employees.Any(e => e.Age < 25);
  • employees.Count(e => e.Age < 25) > 0;

How can I prove this? Well, newer versions of CodeRush have a built-in decompiler so you can look at the source code of these methods (like Reflector does). I’m sure there are other tools out there that do the same… anyway, here’s an (ever so slightly simplified) sample of the implementations of the Count() and Any() methods. First, the parameter-less versions: –

image

image

The former optimises where possible, but if it can’t, has to fall back to iterating over the entire collection. The latter simply falls out if it succeeds in finding the first element.

Now here’s the predicated versions of those methods: –

image

image

The former has to iterate over every item in the collection to determine how many passed the predicate – there’s no optimisation possible here. The latter simply finds the first item in the collection that passes the predicate and breaks there.

Conclusion

Having read through those code samples, re-read the initial example of Any versus Count and ask yourself why you would use Count Smile

Again, just to drill home the point – there is no magic to LINQ. The C# developers did a great job optimising code where possible, but at the end of the day, when you have several options open to you regarding queries, make sure you choose the correct option for the right reason to ensure your code performs as well as possible.

CodeRush for beginners!


Quick post just highlighting the fact that the newest versions of CodeRush have had a few really good features added which makes CR much more accessible for new users.

imageMost important of all for new users is the addition of multiple settings schemes, including a “FrictionFree” scheme.

My main criticism of CR has always been that the barrier to entry was relatively high given that some keyboard shortcuts are different from VS out-of-the-box e.g. Code Templates initialise with space (rather than Tab as per Code Snippets), and that they are initially a hindrance rather than a help. The friction-free scheme tries to use all the existing keyboard shortcuts rather than changing them, whilst essentially turning off any “implicit” CR features that you might see as interfering with your standard way of coding e.g. smart brackets, enter, IntellAssist are all turned off by default.

This is much more like the CodeRushXpress way of working, which is basically a single key-press to bring up the Refactor smart tag (the ‘ key) and not much else, and is definitely the easiest way to get started (indeed, when I first started using CR, I basically did this and then brought in different features one-by-one).

I would like to see an “import/export” profile though – perhaps there’s already one there, but I’m yet to find it – which would be good for settings up new installs.

There’s also now a useful “keyboard shortcuts” modal banner that you can bring up at any time which gives you common shortcuts at-a-glance.

Conclusion

Essentially these features means that CodeRush “fits in” with your existing VS habits rather than taking it over and forcing you to change the way you word. It also means that if you pair with another dev, they won’t get all confused by the funky CodeRush magic that happens just by pressing space Smile

Having said all of that – the “real” CodeRush shortcuts are undoubtedly extremely efficient, and now that I’ve gotten used to them I could never go back…

Final thoughts on Code Rush


Having now spent a fair amount of time with the “full” version of CodeRush + Refactor, I thought it best to give a sort of conclusion as to my experiences with it.

Overall thoughts

Overall, my experiences are largely very positive, particularly around the general, frequently used refactorings – little features like being able to hold ALT to move to the next word in a symbol, or the “expanding” selection using NUMLOCK + / –, are excellent and I quickly miss them when using a non-CR . Many of them help keep your code clean, and generally they save time. There’s a very, very good summary of the main features of the full CR package here.

Criticisms

However, my original concerns still remain with respect to some of the features. The code templates, whilst very useful, still gets in the way more often than I would like, because it sometimes overrides intellisense when you don’t want it to i.e. if you press space to select the current intellisense suggestion, you often find that CR has “stolen” the suggestion and replaced it with a code template of its own. I ended up changing the shortcut for templates from space as I got too frustrated with it.

I also found the banner / help watermarks generally annoying and quickly turn them all off – I suppose each to their own, but for me they’re a definite no-no – especially the abnormally giant “build failed” that you get if you try to run unit tests using the CR test runner.

image

Code Analysis is generally quite useful – some of the rules I find overly strict and turn off but others are good to have as a failsafe, and it doesn’t hurt to have them on I suppose.

Overall

Despite the above misgivings, CodeRush overall is excellent. There’s a good support system in place, and an extensible engine which allows new plugins to be written (although the only one I downloaded never did work for me…). But it’s the little things that do it for me – things like underlining colors with a link to a colour picker, or the super-fast “live” renaming of symbols, or the streamlined reorder parameter refactor etc. etc. As such, a number of these features do live within CodeRushExpress, and I’d recommend using that rather than nothing at all – but the full CodeRush does indeed have many more features and refactorings such that I would notice the difference without it.

You have to invest the time in using it – watch the videos at a pace that you consume and retain the information, or use the CodeRush live helper window – but as a productivity tool, it’s an excellent way to save time (and therefore dollar bread).

Highly recommended (and at the risk of getting flamed, highly recommended ten times over Resharper, which on the rare occasions that I’ve had to use it, I’ve hated it with a passion).

A quick update…


Just a short update on my lack of blogging lately. I’ve actually only recently got back to proper full-time coding now as my house move is almost finally complete. As of today I even have a table I can eat dinner off.

Anyway… I’ve been finishing off my CodeRush review (honest) and also lately trying out the full DX control suite (or at least, the WPF subset of it) within a PRISM application and trying to fit the controls into a MVVM scenario.

I’ve also book a couple of books for bedtime reading… Jon Skeet’s C# In Depth, as well as Real World Functional Programming by Tomas Petricek. Now, the former I’m reading through without too much difficulty – it’s (so far at least) just confirming what I know and putting it in context. The other book I’m finding tough going, though. I really have to concentrate to get my head around a lot of the concepts being chucked out there as every page has new things in it that I’ve never really considered. I’m hoping to write some F# in the future, I like the benefits of this style of programming but having tried and failed a couple of times already, this book looks like a good way to finally get into the language.

CodeRush Review Part 2


Continuing my review of CR…

In my first posting I gave an overview of some of the main differences between CR and CRX. I want to touch upon some of the other features that I didn’t mention in my last post, as well as give an update on how I’m finding using CR.

Code Templates

These can be described as code snippets on speed. If you don’t use snippets, you probably aren’t going to use these. If, on the other hand, you do use snippets, you’ll probably want to try these out. Code Templates are like snippets insofar as they expand a few characters into a code block e.g. “c” will expand into a class with a default constructor, and put the cursor over the class name.

Templates are powerful as they are context aware, so the above example will not fire if you’re in the middle of a method etc.. You can also chain them up e.g. “ai” will create a private auto-implemented property of type Int (a = auto implemented property; i = int). You can read more here to see just how powerful and flexible this system is; here’s a combination which creates a public generic property collection:

image

becomes

image

Nice. There are two caveats with this system, however.

Firstly, you need to invest some time and effort in learning how to use these to get the most benefit – you need to first learn the shortcuts – which you can do slowly e.g. one a day. But more than that, you need to change the way you declare some things e.g. consider the following declaration:

protected int MyIntProperty { get; set; }

With CodeRush, you would not type “protected” first – instead, you would: –

  1. Type the appropriate code template (“ai”)
  2. Press space
  3. Enter the name of the property
  4. Then use ALT + down to change the accessor from private to protected. You cannot simply type protected first and then ai as CodeRush does not understand the context and does not fire the template.
    Secondly, and more importantly, code templates sometimes badly get in your way. Example: You want to get a count of all football teams names starting with the letter “A”. You start typing the following: –

image

“f” will be your lambda expression variable. You press space with the intention of next typing “=>”. However, at this point, CodeRush jumps in and using the code template system, replaces “f” with false:

image

Obviously, not what you want! So, you delete the last four characters and hit space so you can put in your =>, only for CR to jump in again… and again. This is extremely annoying; I’ve in fact have ended up using the letter x for such occasions as this is a “safe” character that CR won’t swallow up.

Another example is when you’re typing and VS intellisense pops up to help you.

image

You can normally now press Space and VS2010 will select footballTeams for you automatically. CodeRush unfortunately overrides this, and replaces it with a “for loop” template!

image

What’s extremely frustrating is that the intellisense says footballTeams, but when you press space, you get something completely different. This is a classic example of a feature “taking over” VS and making you change your way of working simply to “live with” that feature, rather than supporting you when you need it. To work around this, I now have to type a few more characters to avoid hitting a CR template – or press Enter instead of Space. Again, having to change how I work.

Code Templates are a really powerful feature (if a little bit of a black art), that if you invest the time in, will pay off quickly. I just wish it didn’t get in the way so much when you didn’t want it.

CodeRush in general

Well, I uninstalled CR and re-installed CRX for a day or two to see how I found going back. I didn’t mind it so much – whether that’s a testament to CRX or simply because I haven’t learnt enough of the power features of CR, I don’t know. I did miss some features, though e.g. the extra refactorings and the IDE enhancements.

I’m still not using the full set of CR features – for example, the unit test runner and the code analysis are still not in use for me, and I’m still trying to understanding exactly how the intellisense enhancements work – but I’m growing more and more used to it now.

CodeRush Review Part 1


I decided to give the full CodeRush + Resharper! suite a go, with a view to upgrading from the free (and excellent) CodeRush Express Visual Studio 2010 plugin.

I really like CRX, to the extent that in the past I have explicitly removed an install of Resharper because it interfered with CRX too much. So, I was hoping that CR would be more of the same sort of goodness that CR has.

Well, it has lots of things in it, some that I like a lot – but also some things that I’m not a big fan of and that I think still need some work on.

Unfortunately when I tried running it last week I completely gave up on it after an hour or so, and ended up uninstalling it completely. I then caught my breath and decided to give it another go…

As I’m writing this over a period of time, my intention is to give feedback on it over the coming days / weeks as I get to grips with it more and more. So, without further ado, here are my initial thoughts a few days later after install: –

The good

 

Extra refactorings

There are a multitude – dozens, if not more – of new, and mostly excellent refactorings ranging from creating an “else” statement to splitting conditionals to combining return statements. And now I can also rename a class and automatically rename the associated file. As always, you need to spend some time to learn what they are and how to use them – I certainly haven’t found them all – but if you liked the ones in Code Rush Express, then you will be very happy at what is in here.

Tab to next reference

Taken out of CRX since VS2010, this is now back. Wahey!

IDE enhancements

You get a load of addition icons and such added alongside your methods, fields, properties etc. – much like the (sadly no longer free) VS10x Edit View Enhancer. These are a handy way of visually making a large class easier to navigate.

Code Metrics in the IDE

Each method can now also have a little number next to the declaration which represents a code metric e.g. cyclomatic complexity or maintainability index. A nice feature – and it would be nicer if this existed at the class level, too.

XML editor enhancements

I noticed a number of refactorings when editing XML files, such as splitting attribute declarations over multiple lines, expanding selections (as per C# with the numlock keys), and even things like underlining colour declarations in XAML with the colour itself; clicking it brings up a colour mixer – nice.

The not-so-good

 

Installation

The install proceeded without a hitch (having unchecked CRX and just left CR and Resharper!) in there. However, immediately after install and starting VS, I noticed that the usual CTRL ‘ keyboard shortcut wasn’t working – I needed to restart VS again before it woke up. Not the best start.

Intellisense enhancements

There’s an Intellisense enhancement which sometimes tries to guess what symbol you’re trying to type. So if you have declared a variable called  myFirstSetOfResults and start typing “myFi”, CodeRush will try to fill in the variable – you can press Enter and carry on, or Escape to cancel it. (This is effectively a shortcut for pressing CTRL + Space and then Enter which is built-in to Visual Studio). Unfortunately, however, CR had a habit of kicking this in whilst creating a foreach declaration e.g.

foreach (var myFi...)

At this point CR will try to finish off this declaration as well – when you obviously want to enter a new, unique variable name for the temporary variable. It confused me, and shouldn’t have been popping up at this point in code. So far I’ve had mixed feelings about this feature – it’s sometimes handy, other times it just got in my way.

Test Runner

I tried this for about an hour and then gave up. The results window looks nice – sort of like the Resharper one, with a split window for the failed tests and the stack trace etc.. However, the default behaviours are somewhat annoying if you’re used to the VS test runner: double clicking does not go to the test; it reruns it.

It also adds some nice artefacts to the VS IDE – alongside each test (in code) it shows an icon whether it passed or not on the last run, and you can mouse over it to get more details of the test. This is handy (especially if you can bind it to a keyboard shortcut). However, I ended up stopping using the runner for a couple of small but annoying reasons. Firstly, every time I ran a unit test VS decided to do the “ping” error sound – annoying; secondly, and more importantly, CR didn’t always rebuild my assemblies after I made code changes so unit tests were failing even though I’d fixed my code – so I needed to keep manually doing a rebuild and then running the unit tests.

Maybe I’ll try this again in a week or so.

Find All References Dialog

The standard “find all references” dialog has been replaced by a new CR one. I didn’t like it and removed it almost immediately – primarily because they’ve only replaced half of it i.e. SHIFT + F12 goes to the show references dialog, but F8 doesn’t cycle through each reference in the code window. This is something that I simply could not understand – why replace just half of the use case by default? As it stands, the new dialog (which seems to be a sort of find all references / call hierarchy hybrid view) ends up removing functionality because of the lack of this shortcut.

Notifications

You get a massive “Build Failed” banner on the screen when you try a build via the test runner and it fails. I ask you, what exactly is the point of this? It stays on screen for about 5 seconds and then disappears. I found it extremely annoying. Why not just do the usual display of the error dialog tool window? Yes, you can remove it – but why put it there in the first place.

Keyboard shortcuts

This has been the most annoying part of the install so far. CR replaces your keyboard shortcuts with its own, without first bothering to check if they are in use. For example, if you have the VS Productivity Power Tools installed, it comes with a useful “find” feature which has the shortcut CTRL + 3. CR replaces this with a “create region” enhancement – which is a nice feature, but it’s not what I wanted when I hit CTRL + 3. There were a few of these scattered throughout and really drove me mad, as I had to go through the overly-complicated options screen to remove the shortcut from CodeRush. CR simply should not be replacing keyboard shortcuts with anything other than something that does the same as what it did before (e.g. as they have done with the F2 rename refactor), or not doing anything at all.

This is similar to one of the primary reasons why I didn’t like Resharper – it contained a non-standard set of keyboard shortcuts that ended up slowing me down, and I felt like I was learning something that would mean I would end up relying on them and not being able to code effectively without them.

Live Code Analysis

This is a good idea in principle, similar to the resharper one – although I need to find out what the keyboard shortcut for it is – but there were a few things that I didn’t like. Firstly, it shows unused declarations in grey – a good idea, except it did it on the object and event args of event handler methods as well, which are often ignored anyway. And if those event handlers are linked up in XAML, at first the IDE did not detect this and showed the entire method signature in grey – making me think that it was not being used. Only after I had saved and waited some not-insignificant period of time did the code analysis thread “catch up” and figure it out. I found this quite annoying and didn’t really help me because it was fairly slow, and I ended up disabling it.

Conclusion

My initial thought was “wow, there’s a lot in here!”. That’s a good thing – but for someone like me that’s been using CRX religiously for 18 months or more, I got a lot more than I bargained for. I thought I’d have a load more refactorings, and some other bits and pieces, and bobs your uncle – an easy upgrade. Instead, I also got the code analysis, unit test runner and other IDE enhancements, new keyboard shortcuts etc., and I’ve ended up disabled a few of the “extra” features (at least for now) because they were simply overloading me with new things. I plan to try them out in isolation in order to evaluate them properly.

I should point out that I got some good guidance on upgrading to CodeRush from CodeRushExpress from Rory Becker (thanks Rory!), which, once I’d read them, did make my life a little easier.

VS2010 Extensions


Some good VS2010 extensions that I’ve found recently…

  • Highlight all occurrences of selected word – VS2010 sort of does this out of the box, but this is much better. Double-clicking any word will highlight all occurrences, even string matches (within quotes) or if they are in collapsed regions (in which case the region is highlighted)
  • Solution Load Manager – you can specify at the solution level which projects to load up-front and which to load either explicitly or when accessed through solution explorer. A really good idea which can massively speed up solution load time.
  • PowerCommands for VS2010 – As per 2008. It (sadly) even has the same annoying behaviour of opening and pinning the Undo Close pane on startup!
  • ADO .NET C# POCO Entity Generator – generates POCO objects for your EF model.

I’ve also been trying out CodeRushXpress v10 on VS2010 – sadly it seems to still be quite unstable, often going walkies and simply not responding to the CTRL ‘ key-combination.