Monday, 28 December 2009

Reflections on Optimisation – Part 2, Existing Frameworks

Yesterday I introduced some topics on reflection performance, and investigated briefly the options to model abstraction, concluding that an abstract base-class / concrete subclass was a reasonable approach.

At this point, you could ask “so?” – the point is that I need a pretty optimised way of getting / setting data. So how about existing frameworks? Raw reflection? (PropertyInfo) ComponentModel? (PropertyDescriptor) HyperDescriptor? Let’s compare these options. I’ve setup a deliberately basic test rig, that simply tests each of these in a tight loop (again, deliberately avoiding boxing etc). As before, I’ll post the full code at the end of the series, but here’s the crude comparison:

Implementation Get performance Set performance
  • No wrapper (baseline)
  • Base class
  • HyperDescriptor
  • PropertyDescriptor*
  • PropertyInfo*
19, 37, 42, 79, 131 38, 55, 80, 131, 148
(numbers scaled, based on 750M iterations, except “*”; lower is better)

You might think “hey, PropertyInfo / PropertyDescriptor” aren’t too bad! Except for the *, which means that in order to get them into the same scale I had to introduce the line:

            count /= 100;

Where "count" is the number of iterations to perform. And even with this they are at the bottom of the table (by quite a margin). Yup – they really are over 100 times slower, which is why we need to optimise in the first place!

You might also conclude “HyperDescriptor doesn’t do too badly – just use that and move on”. Which would be valid in most cases (I’m pretty happy with that code, especially since that was my first foray into IL), except:

  • It wouldn’t let me investigate field vs property, polymorphism, and the other common “is this faster” questions I mentioned in part 1
  • It relies on constructs that don’t exist in CF / Silverlight, and which it would not be useful to duplicate (yet I need this for protobuf-net)
  • Sometimes the extra crank of the optimisation handle matters

Summary

In this discussion, I hope I’ve demonstrated that there really is a problem just using PropertyInfo etc, that we can overcome (evidence: HyperDescriptor), but we would hope to do so in a simplified, minimal way that can be modelled (perhaps with slightly different implementations) on all the common frameworks.

Sunday, 27 December 2009

Reflections on Optimisation – Part 1, Abstraction

Introduction

I want to take a few blog posts to discuss some ramblings on performance, reflection, and library code. The common “knowledge” is that reflection is slow and to be avoided, but this is missing the caveat “when used inappropriately” – indeed, as part of library / framework code it can be incredibly useful and very fast. Just as importantly, suitable use of reflection can also avoid the risk of introducing bugs by having to write repetitive code manually.

Between my musings on the Expression API, work on HyperDescriptor, and many questions on sites like stackoverflow, I’ve looks at this issue often. More, I need to do some work to address the “generics” issue in protobuf-net – so I thought I’d try to combine the this with some hopefully useful coverage of the issues.

The setup

What I am really after is the fastest way of getting values into and out-of objects, optimised as far as is practical. Essentially:

    var oldX = obj.X; // get
obj.X = newX; // set

but for use in library code where “X” (and the type of X) isn’t known at compile-time, such as materialization, data-import/export, serialization, etc. Thanks to my learning points from protobuf-net, I’m deliberately not getting into any “generics” answers from this. Been there; still trying to dig my way out.

I plan to look at a range of issues in this area, including (not necessarily in this order):

  • types of abstraction
  • fields vs properties vs polymorphism
  • mechanisms for implementing the actual get/set code
  • boxing, casting and Nullable-of-T
  • lookup performance
  • caching of dynamic implementations
  • comparison to MemberInfo / PropertyDescriptor / CreateDelegate

Note that this is an area that can depend on a lot of factors; for my tests I’ll be focusing on Intel x86 performance in .NET 3.5 SP1. I’ll try to update when 4.0 is RTM, but I’d rather not get too distracted by the 4.0 CTPs for now. Even with this fairly tight scope, I expect this to take too many words… sorry for that.

First problem – abstraction

OK; so essentially we expect to end up with some API similar to reflection, allowing us to swap into existing code without re-writing it:

    var prop = SomeAPI["X"]; // perhaps passing in
// obj or a Type
object oldX = prop.GetValue(obj); // get
prop.SetValue(obj, newX); // set

This should look very similar to anyone who has used reflection or TypeDescriptor. And I plan to compare/contrast to the default implementations. So: is there any noticeable difference in how we implement “prop”? This might give us a better solution, and it also impacts how I write the tests for the other issues ;-p I can think of 3 options off the top of my head:

  • An interface with concrete implementation per type/property
  • An abstract base class with concrete implementations per type/property
  • A sealed implementation with delegates (of fixed delegate types, one matching the get, one the set) passed into the constructor

There is no point introducing any dynamic code at this point, so I’ll test each these implemented manually (deliberately avoiding boxing), compared to a direct wrapper (no abstraction), and direct access (no wrapper, as per the original introduction):

I’ll post the full code later (and add link here), but this gives the initial results:

Implementation Get performance Set performance


  • No wrapper (baseline)
  • No abstraction
  • Base class
  • Interface
  • Delegates

9, 29, 30, 43, 71 31, 55, 57, 61, 84
(numbers scaled, based on 750M iterations; lower is better)

The conclusion of this is that, for the purposes of representing a basic property wrapper mechanism a base class is just as good as a wrapper with no abstraction – so we should assume a base-class implementation. An interface is a little slower – not enough to be hugely significant, but a property wrapper is a pretty specific thing, and I can’t see the benefit in making it more abstract than a base class.

For the purpose of adding context, the (very basic) code I’ve used to test this base-class approach is simply:

image

Summary

It might not seem like we’ve come far yet; but I’ve described the problem, and narrowed the discussion (for the purpose of micro-optimisation) to implementations using a base-class approach. Which is a little annoying on one level, as the delegate approach (via DynamicMethod) is in many ways more convenient.

Friday, 18 December 2009

Crimbo Tooling Presents

As part of development, I always try to keep my eye on any tools that make my life easier. Sometimes that means IDE tools – and sometimes more general tools. I just wanted to share the things that have helped me recently. Maybe you’ll decide to treat yourself for xmas ;-p

VMware

Recently, Player 3 (free) and Worstation 7 (£$€) were released; any developer not using virtual machines regularly is missing some serious tricks – and now that the free “Player” product allows you to create machines (bad news for EasyVMX?) there is no excuse not to. I compared it (informally) to the Windows (7) Virtual PC, and I’ve found Workstation much nicer to get along with. I honestly can’t quantify why (except for the really annoying pause whenever I resized a console in WVPC), but it just feels slicker.

Fences

Desktop icon management; everyone I’ve shown it to simply loves it (and they are still using it). Fences is, in some ways, a flashback to Program Manager (for those of us who remember Windows 3.x).

You know how your desktop accumulates cruff? Fences lets you group them – both visually and logically (drag groups instead of individually). And perhaps more importantly, hide/show them all (or your choice of them) in a single action (double-click on the desktop.

Some people might (and have – and no, I don’t have that many!) criticize me for keeping anything on the desktop – but it is the biggest UI element I have; why should I ignore it? It lets me keep things in logical groups, uncluttered, and easy to hide / show. Just lovely.

MaxiVista

When I’m in the office, I switch from my laptop to my workstation (more “grunt”, fixed dual head, etc) – but my laptop is still useful. Thanks to the joys of RSI, and my freaky keyboard/mouse setup, switching between the two is a pain. A KVM is an option, of course, but involves messing with wires, and doesn’t let me do everything at one. Step up MaxiVista! This great bit of software lets me configure my laptop as a monitor for my desktop PC – either as an extended desktop or for remote control (and I can toggle between the two with a single key, conveniently placed (on my freakboard) next to the Windows key.

Extended desktop: as you expect; drag a running app off the fixed monitors, and it appears on the laptop. It works brilliantly; sometimes (not always) there is a tiny bit of latency (similar to remote desktop etc, which makes a lot of sense), so I mainly use it as the monitor with static content (the requirements / spec, for example) rather than the monitor that I’m using for active UI work.

Remote control: in another mode, move the mouse off the monitor and it takes charge of the laptop; no noticeable latency now, as it is just sending the mouse movements and keyboard, and I find this fantastic, for example, for cross-OS testing (my laptop and desktop run different OS). No messing with KVM, VM, or RDP – just move to the computer you want.

There is also desktop mirroring for showing the same desktop somewhere else; I haven’t needed this yet, though.

It supports up to 4 remote monitors, and works alongside your existing multi-monitor setup, so you can go mad. I don’t think I could gainfully use more than 3, but hey.

Got Mono?

This week, a lot of new shiny Mono tools were released. Mono has always been something on the edge of my awareness, but I haven’t really had the time to get into it fully, in part because the tooling was… “incomplete”. I don’t mean that as an insult; merely that for most Windows devs, Visual Studio would be more attractive.

First: I’d better clarify my position. I really like Visual Studio; it works great for most of what I need – but with some cross-platform open source projects under my belt, and being aware of the common “community” (stackoverflow etc) questions about cross-platform, I now many of the pain points. I’m happy that both set of tools can co-exist without anyone getting upset.

The main time I started getting into Mono was for protobuf-net – I've had a lot of positive feedback from people pleased that it works on Mono, but my tooling for testing it on Mono has always been poor.

Step up MonoDevelop; with the new 2.2 release, IMO this actually starts to become a reasonable proposition for regular development (maybe not winforms…). With support for (among others) ASP, ASP.NET MVC, Moonlight and Gtk# – and inbuilt SVN and NUnit support it shouldn’t be dismissed. I’m in the process of ensuring that protobuf-net works (and passes the tests) in both IDEs. There are also spikes around that show Android development on MonoDevelop.

Additionally, Mono 2.6 introduces much better support on a wide range of APIs – most notably borrowing the Silverlight WCF stack, and things like the DLR. My only problem now is figuring out how much “old” Mono to support. I’m quite tempted to make 2.6 my new baseline, for simplicity.

Of course, that isn’t all – with MonoTouch for iPhone, and Mono Tools for Visual Studio, the Mono eco-system is truly starting to come into its own. I plan on spending a lot more time getting to know it more than I already do, and have proposed a session to present at ddd8. Interesting changes.

Wednesday, 2 December 2009

Red Gate and the Holy Grail

I’ve been playing with the EAP version of Red Gate’s .NET Reflector lately, which is a very nice addition to already excellent Reflector that we all love. I hadn't opened VS2008 on my test rig for a while, but did today... the “update thyself” message is pure Pythonesque joy:

First shalt thou download the Holy Build, then shalt thou count to three, no more, no less. Three shalt be the number thou shalt count, and the number of the counting shalt be three. Four shalt thou not count, neither count thou two, excepting that thou then proceed to three. Five is right out. Once the number three, being the third number, be reached, then runnest thou thy Holy Build of Reflector, who being naughty in my sight, shall snuff it.

Anyway, the EAP is discussed here, with the current build always near the top on the support forum. It certainly makes my life easier when debugging! (caveat: note the warnings in the posts – i.e. don’t go crying to Red Gate if it breaks your computer, pawns your car, or takes the cat to a tattoo parlour “for giggles”).