Thursday, 24 September 2009

Numeric keypads; what is the point?

As I hinted the other day, I've recently had some stress/RSI symptoms in my arm. Nothing too serious, just definitely worth fixing ASAP. I'm by no means crippled with RSI or anything, but I am on a mini-crusade for programmer-health, and want to help others avoid unnecessary stress / irritation.

I had a very productive session with a physiotherapist today, who made some really constructive and pragmatic points (for example, demonstrating quite simply and clearly that the curve on my corner-desk points the wrong way, and simply swapping to a mirrored desk could help hugely).

But one startling point she made while observing me; as a programmer, I move frequently between the keyboard (in my case a decent ergonomic split jobbie) and the mouse (now a shiny new "vertical" model) - code a few lines, use the mouse to click a few buttons, test a few things via the UI - rinse, repeat.

Sure, I use the keyboard shortcuts, but I would struggle to remember the hundreds of magic key-presses and "chords" that drive Visual Studio.

Very rarely do I use the numeric keypad. Heck, I also use a laptop, and the only time I find myself looking for Num Lock is when my password inexplicably doesn't work. Yet every time I move between keys and mouse I have to travel this pointless distance.

Lets not do that

Numeric keypads; absolutely useless. Underused, oversized, badly placed, and they don't agree with 'phones on which way the numbers should go.


Goldtouch Keyboard

She gave me a tip to simply try a keyboard without one, letting me have the mouse much closer. You can pick up a "Goldtouch" ergonomic keyboard (sans keypad) for about GBP25 at Amazon. This is so simple and so obvious that I'm just stunned that people insist on still including it, even on "ergonomic" keyboards. If it is so ergonomic, why is it causing unnecessary travel?!?!


USB Numeric Keypad
If you want a keypad (and I do find them handy occasionally), then buy a USB keypad (like they sell for laptops) - roughly GBP10, and that is for the models that double as a handy USB hub. If you're right-handed, stick it on the left, or on the far side of the mouse - whichever you prefer and find most comfortable. Plus you can move it to either side if a "sinister" shows up at your desk.

Join the revolt! I invite you to ditch (or move) your keypad today!

Wednesday, 16 September 2009

protobuf-net vs NetDataContractSerializer

In a user-group meeting yesterday, I was talking briefly (in a “grok” session) about “protocol buffers” (protobuf-net in particular), and I was asked a question about the comparison to NetDataContractSerializer. I didn’t have the answer to hand (I only had numbers vs DataContractSerializer), so promised to find out…

First; note that the key difference between DataContractSerializer and NetDataContractSerializer is (as I understand it) that NetDataContractSerializer includes more type metadata. This makes it possible to do a few things involving “object” and unanticipated subclasses (which can be useful), but renders it .NET-specific (and less version-tolerant).

The test

As per my existing test rig, I test 1000 iterations of a moderately large extract from the Northwind sample database (into some pretty-standard POCO types); I simply extended this rig to incude NetDataContractSerializer. For completeness, I have 3 variants of the tests, tested separately each against a different set of serializers:

  1. LINQ-to-SQL generated classes with serialization enabled at the data-context; suitable for protobuf-net, DataContractSerializer and DataContractJsonSerializer
  2. as the first test, but with the LINQ-to-SQL bits hacked out and [Serializable] added (to make it suitable for the core binary .NET serializers); suitable for protobuf-net, NetDataContractSerializer, DataContractSerializer, DataContractJsonSerializer, BinaryFormatter and XmlSerializer
  3. as second test, but with ISerializable and IXmlSerializable implemented to support BinaryFormatter and XmlSerializer via protobuf-net

The numbers and analysis

Since only the second test supports NetDataContractSerializer, that is the one I’ll focus on (with results from the 3rd test included for interest only, marked *); here’s the numbers:

Serializer Size (bytes) Serialize (ms) Deserialize (ms)
protobuf-net 133,010 10,769 23,511
NetDataContract
Serializer
992,203 29,343 91,453
DataContract
Serializer
772,406 16,272 66,755
DataContractJson
Serializer
490,425 29,604 135,125
BinaryFormatter 276,366 67,151 56,253
XmlSerializer 1,043,137 29,257 38,528
BinaryFormatter* 133,167 12,095 24,653
XmlSerializer* 177,41012,189 31,827

Some interesting points; firstly, for my sample data it is a myth that WCF’s binary type-centric serializer (NetDataContractSerializer) is going to improve things over xml (DataContractSerializer). Both in terms of bandwidth and processing time it is worse on every front. The biggest advantage of NetDataContractSerializer (in this case) is that the type model is more flexible in terms of interfaces, “object” and unknown subclasses; but this also makes it entirely non-interoperable. Of course, some details of the SOAP envelope used by the binary type-centric WCF transport may be more efficient – but I’m looking at payload for these tests.

Secondly (and fortunately for me) it yet again proves that google know how to do data transport; with protobuf-net being the clear winner for both bandwidth and processing time.

But for me, another point that I’d like to highlight is versatility and compatibility; the same classes can be used happily by a wide range of serializers (above), and presumably a few others too. For the record, the entities in the above test don’t even have any protobuf-net-specific attributes (the outer-most wrapper does have them, but only because at some point in the distant past I wanted a way to compare/contrast some protocol-buffers-specific details, which can only be controlled via the custom attributes).

Other thoughts

As with all performance tests, your specific environment and data may be an important factor. But based on the above numbers it may be reasonable to assume that protobuf-net stands a good chance of holding its corner.

Finally; following some unrelated conversations at the same user-group (they kept me pretty busy), I stress that tight serialization is only part of the story:

  • It can help reduce bandwidth costs and CPU costs associated with (de)serialization, but it won’t help if latency is your issue; protobuf-net makes no claim to change the speed of light.
  • While protocol buffers may be supported on a range of platforms, it is by no means ubiquitous; if your biggest demand is portability, perhaps use SOAP/WSDL (or offer both SOAP and protobuf-net on separate endpoints).
  • By itself it won’t solve all your disconnected woes; although it can presumably be used in tandem with any message-queue based solution you might dream of.

Tuesday, 15 September 2009

The Most Important Programming Book

A holy war, you might think, for any of author / architecture / language. But for full-time professional geeks, how about a book that is much more important than any of these mere implementation details:

It's Not Carpal Tunnel Syndrome! You might be thinking “huh?”, but as IT professionals (and programmers in particular), we are hugely exposed to RSI in our professional life. Don’t underestimate the risks; we do this job to pay the mortgage/rent, after all.

I switched to an ergonomic keyboard years ago (one of the Microsoft models with the split key groups), after a warning shot – but the importance of things like correct posture / equipment is huge. But my point here: don’t wait to be a sufferer: take preventative steps now to avoid problems (and pain) later. Even those fancy vertical / air mice are a snip compared to just a few days off work.

Wednesday, 9 September 2009

Stickers – now what to do with them?

For any stackoverflow users, the stickers are real – Jeff was kind enough to send mine directly, rather than wait for DevDays. I knew that would be useful!

Compulsory wooden-table shot:

SDC10088

They’re a little smaller than I expected, being only slightly longer than my mobile ‘phone. Now… if only I can think of what to do with them… so far, I’m wondering if they might make serviceable plasters (band-aid if that doesn’t translate). Or (edit) maybe a laptop-chassis emergency repair kit? (my last laptop survived 2 large cracks for a considerable time). Or I might drag them along to a user-group and see if there are any takers.

All other suggestions welcome…

Saturday, 15 August 2009

Using reflector to understand anonymous methods and captured variables

C# 2.0’s ability to magically hoist “captured variables” into classes is often misunderstood, and there are a lot of tricky edge cases (especially when combined with the notorious “foreach” glitch).

So; how can we understand what is going on? Usually, the first tool to look at is reflector; so lets try with a simple example:

int div;
do { Console.WriteLine("Find numbers divisible by..."); }
while (!int.TryParse(Console.ReadLine(), out div));

int[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17 };

var filtered = data.Where(num => num % div == 0);
foreach (var i in filtered) Console.WriteLine(i);

So what is really happening here? Load it into Red Gate’s .NET Reflector, and by default it doesn’t actually seem to help us much, ironically because it does such a good job of interpreting the code:

image

I’ll forgive it for interpreting “Where” as LINQ query syntax, since the two are 100% interchangeable. What we don’t want to have to do is look at the IL – it is, lets be honest, not fun – here’s a small fragment of it:

image

But if you look at the options in reflector:

image image

you can choose the level of magic it applies. Lets try scaling it back to .NET 2.0 (a trick I use often to investigate the lambda Expression API):

image

Here, it has got rid of the query syntax (and would remove lambdas, too), and now uses the anonymous method approach (“delegate” etc), but it hasn’t really changed much (since C# 2.0 still allows captured variables in anonymous methods).

As an aside, it is very curious that it has left “data.Where” (rather than “Enumerable.Where(data)”) – I have left feedback with Red Gate ;-p

So lets try .NET 1.0:

image

Now we’re talking! Here we can clearly see the class (<>c__DisplayClass1) and local variable / instance (CS$<>8__locals2) that is used to do the hoisting, the hoisted field (CS$<>8__locals2.div) and the anonymous method (CS$<>8__locals2.<Main>b__0) that provides the logic implementation. All hyperlinked up for easy navigation - to the compiler-generated class; this is invaluable for anything non-trivial:

[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
// Fields
public int div;

// Methods
public bool
b__0(int num)
{
return ((num % this.div) == 0);
}
}

Interestingly, we can also scale it back a level further to “None”; which shows compatible C# without candy like “foreach”. This is verbose for C#, but terse compared to the IL version; here’s the “foreach”:

image

The declaration isn’t in the above grab (it is at the top of the method), but this also highlights how the iteration variable (“i”) is declared outside of the loop, hence the “foreach”/”capture” issue.

Again, I find it quite fun that in this level of optimisation it doesn’t show “foreach”, but knows about extension methods; but I’m not complaining – it seems ungrateful to criticise such a minor glitch in such a wonderful (and free) tool. But for people using non-standard LINQ implementations (or just to be true to the optimisation level), it would be nice if it showed this appropriately.

So there you go; yet another way to use reflector.

Who says you can’t instantiate an interface?

(update update: the question has been raised: "should we use this in our code?" - and in answer: heck no! this is just a fun diversion around the edges of the C# spec; leave well alone...)

(update: I just realised that Jon Skeet mentioned this in passing here, too; I'll keep this here, as I think it is intriguing enough to warrant a more targeted post)

If I said that the following is valid C# (all the way back to v1), you might think I’ve been overdoing things:

interface IFoo
{
string Message {get;}
}
...
IFoo obj = new IFoo("abc");
Console.WriteLine(obj.Message);

But the funny thing is… this is actually legal! Or at least, it compiles and runs ;-p As you might expect, I’ve missed out some magic in the above ;-p

It turns out that there is a subtlety relating to how COM imports work… and it is possible to define against the interface a default concrete type. The C# compiler then interprets “new {InterfaceType}” as “new {DesignatedConcreteType}”.

Here’s the missing magic (including a concrete type):

class Foo : IFoo
{
readonly string name;
public Foo(string name)
{
this.name = name;
}
string IFoo.Message
{
get
{
return "Hello from " + name;
}
}
}
// these attributes make it work
// (the guid is purely random)
[ComImport, CoClass(typeof(Foo))]
[Guid("d60908eb-fd5a-4d3c-9392-8646fcd1edce")]
interface IFoo
{
string Message {get;}
}

(see footnote) I'm struggling to find a mention of it in the C# specification (3.0), though... indeed §7.5.10.1 says:

"The type of an object-creation-expression must be a class-type, a value-type or a type-parameter. The type cannot be an abstract class-type.
The optional argument-list (§7.4.1) is permitted only if the type is a class-type or a struct-type."

So a non-legal feature? I'll let you be the judge...

Footnote: Mehrdad has clarified that the fact that it is omitted from the specification is OK because §17.5 allows any of of attributes in the System.Runtime.InteropServices namespace to break all the rules ;-p

Tuesday, 11 August 2009

Expression as a Compiler

It is no secret that I like playing with the Expression API. Well, I've finally spent some time collating some of my thoughts into a semi-coherent discussion on InfoQ. I hope it is useful to somebody.