My oh-so-valuable time: how far is too far?

Most “regular” folks probably don’t realize that there are religions among software developers. Among these religions is one whose primary doctrine is “my (the developer’s) time is more valuable than the computer’s.”

Now, I’m not saying this is wrong. On first hearing it, one might even think of it as merely a statement of the obvious. But I’m not talking about common sense; I’m talking about religious conviction, the kind that enables devout individuals to stalwartly adhere to a principle even in circumstances where others might abandon it, or else make some sort of compromise.

I understand the value of my and other developers’ time just as well as the next guy/gal. But sometimes you do reach a point where enough is enough.

Consider, for example, this question from Stack Overflow. The user asking the question proposes the following code as a way of implementing the INotifyPropertyChanged interface without having to pass any parameters to a method call:

public virtual void RaisePropertyChanged()
{
    var frames = new System.Diagnostics.StackTrace();
    for (var i = 0; i < frames.FrameCount; i++)
    {
        var frame = frames.GetFrame(i).GetMethod() as MethodInfo;
        if (frame != null)
            if (frame.IsSpecialName && frame.Name.StartsWith("set_"))
            {
                RaisePropertyChanged(frame.Name.Substring(4));
                return;
            }
    }
    throw new InvalidOperationException("NotifyPropertyChanged() can only by invoked within a property setter.");
}

What is the above code doing? Can you even tell? In case you need some help making sense of it, let’s walk through it together.

Firstly, it’s creating a new StackTrace. That much is plain, right? But why is it doing that?

The idea is that the method above wants to figure out where it’s being called from, so that the caller doesn’t have to tell it. So, it looks at the stack trace, steps through its frames one by one, looks for a frame whose method has a name like “set_PropertyX” (by convention this will correspond to a .NET property setter), takes the portion of that string after the “set_” part, and finally raises the PropertyChanged event with that substring for the property name.

For a full example of all this in action, see my snippet on pastebin here.

The SO question is concerned primarily with performance. The actual title of the question is “Just how slow is this?” To me, the implication of this question is something like: Clearly this is a good thing, assuming it doesn’t kill performance too badly. So, how terrible is the performance? Because if it isn’t extremely terrible then I want to do it.

I’ve got nothing against the user who posted this question. Honestly, it’s a clever idea. Be that as it may, I can hardly believe someone would seriously consider actually doing this.

Just for the record, let’s look at our alternatives, using the code above and not using it.

Using RaisePropertyChanged

// Example of a property implemented using the above code
private string _name;
public string Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
        RaisePropertyChanged(); // Neat! I didn't have to type the property name!
    }
}

Not using RaisePropertyChanged

// Example of a property implemented the old-fashioned way
private string _name;
public string Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
        RaisePropertyChanged("Name"); // 6 more characters, yuck!
    }
}

Uhh… are you looking at that? Never mind performance for a moment; would you seriously prefer to create a stack trace and step through its frames looking for a method starting with the string “set_” than type 6 more characters?!

I know what you’re thinking: it’s not just six characters. It’s those six, another five here, another eight there, a dozen or so there… OK, sure. That’s a fair point. But let’s look at it from another angle. That RaisePropertyChanged method is fragile. It could be called from within a property setter that’s inlined by the JIT compiler; the only safeguard against that is to decorate your setter with the MethodImpl attribute and MethodImplOptions.NoInlining (at which point you’ve already suffered a net loss in terms of how much typing you need to do). Then consider that IsSpecialName check. Here’s what MSDN has to say about that property:

The SpecialName bit is set to flag members that are treated in a special way by some compilers (such as property accessors and operator overloading methods). [emphasis mine]

This is not a guaranteed, specified behavior. It’s a flag that’s used by some compilers. (Yes, I realize that Microsoft’s C# compiler is the de facto compiler that just about everybody uses; but that doesn’t invalidate this concern in principle.) So let’s say it’s not used by whatever 3rd party compiler you’re using for experimentation or whatever other perfectly legitimate reason you may have. Then it’s completely plausible that IsSpecialName might return false, and then… you’ll get an InvalidOperationException for calling RaisePropertyChanged in precisely the context in which it’s meant to be called!

That’s a pretty big “uh oh” in my book.

But you know what? This is all kind of unfair. If the question was originally about performance, then we really ought to be talking about performance. So let’s do that.

Based on my test, using RaisePropertyChanged costs about 2500 times what it costs to raise a PropertyChanged event the “old-fashioned” way, by passing the property’s name (as a string) directly to a method.

2500 times. To save yourself some typing.

To reiterate: I understand that yes, a developer’s time is more valuable than a computer’s time. But this?

This is why I mentioned religious conviction earlier. When you are willing to go this far just to save yourself a few seconds’ worth of typing, it’s a sign—in my mind, anyway—that your belief in this school of thought is approaching the realm of the religious.

About these ads

One thought on “My oh-so-valuable time: how far is too far?

  1. Mark T says:

    There is one other issue with manually typing the property name each time (NOT that I am trying to defend or recommend the questioner’s approach) – and that is that if the property name gets changed it’s possible that the string won’t get updated, meaning the event will get raised with the wrong name. It’s always worried me a bit about the fragility of having to use the property name in a string, but in practice I don’t think it’s actually ever caused me a problem.

    Again, not a reason to follow the approach provided by the questioner, but another possible reason that they may have come up with that idea.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: