Correct, then performant
Rob Conery just put up an interesting post (more on that later) where he talks about my example of optimizing a page from 32 queries to 4. His conclusion to that was:
I think that's a great sample of a page that was created by a developer who clearly doesn't know their way around a tool
No, it isn't. That developer was me, and that was an explicit decision made when we started working. Up to some limit ( I think it is 50 queries per page ), you can do whatever you want for development. I don't want to waste time of performance when I am developing, because it doesn't really matter when I am developing, and later I can easily start optimizing it without touching anything else in the application.
Just to give an idea, the relevant page took about a week to build, fairly complex UI, fairly complex interactions, etc. Performance is something that I can ignore until I need to deal with it, and dealing with it is fairly simple. Total time spent optimizing this page? One & a half hours or so. The result was an order of magnitude improvement in performance.
I see this as a success of this approach, because I didn't have to think about performance at all when I built the page. The fun part? I can reduce the number of allowed queries at any time, and catch any "rouge" page and fix that easily as well. Once you did it once, it becomes very easy to understand what is going on.
That is a great example of deciding what matters and when. The first concern is to get it working, get it looking right, and then getting it working fast and performant.
And no, this is not a license to ignore performance at all (using customer.HugeOrderCollection.Count is still out), but it keep you focused on the task at hand.
Comments
I think Knuth says it best; "premature optimization is the root of all evil."
Maybe you should start reading up on NHibhernate so you can learn your way around. ;)
I whole-heartedly agree with the "premature optimization" sentiment - it's not something to shoot for right off. But at the same time would you trust your devs to come around and tighten the thing up before launch? Isn't this the "I'll just put the pin back in the grenade" theory?
I didn't know it was you who was the original dev :). I'd make a quip about feet and mouth but at the same time - 37 calls on a page? I dunno - that's a reckless if you ask me.
Yes.
Rob:
37 calls on a page? I dunno - that's a reckless if you ask me.
Sounds like a WebForms application :)
Rob:
would you trust your devs to come around and tighten the thing up before launch
If you can't trust your devs to do what's needed.... Why are they your devs?
Ouch, I was trying to not be involved with this, but Rob, c'mon, trust your devs? That's an arrogant statement, hopefully not intentional. It makes me think about those companies that hire two smart guys and a fifteen code monkeys.
The smart guys come up with a framework, and the poor code monkeys have to rely on creativity to work around things that the framework wasn't designed to do, after all it was built prematurely instead of being extract from an use.
I sincerely hope that you do believe that everyone is capable of learning and apply good judgments, so you will trust your devs whatever you assign to them.
Rob,
It is not like I "have devs" :-)
But if I did, I would try to be generously minded and trust them /not/ to begin by optimizing. I would indeed be hoping that they developed exactly as Ayende did in this case: Beginning by fulfilling requirements using the simplest and clearest code they could, then profile, then optimize. Are you suggesting another preferrable development path?
37 sql statements on a page: By itself that figure means nothing. If that is many or few sql statements depends entirely on the amount of stuff on the page. I trust Ayende when he says there was a lot going on in the page.
The 37 statements can't just be compared to the 4 sql statements Ayende ended up with - and one certainly shouldn't assume that "well, I guess those are the 4 statements I would have begun by doing then, since I don't use an O/R Mapper".
I would imagine pretty much any decent developer could bring the number of statements down from 37 once they entered optimization phase and started looking at what could be eagerly loaded etc. But I also imagine it took quite some effort to bring them down to 4!
In my best guessing from experience, a couple of avarage devs with some O/R skills would probably, during optimization, bring the number of statements down to roughly the same amount of statements as would be used by equally skilled devs that were not using an O/R Mapper - after their optimization period. Neither team would end up with just four statements and neither team would start out with as few statements as they would both eventually land on.
I think this scenario is a perfect example of why the abstraction of an OR/M is so useful. You concentrate on building your code against the model and have the luxury of tuning the data access to what you need when you need to tune without having to go back and changing the model.
Sure, it's not an absolute. There's still plenty of things that you can do that you cannot optimize away at the OR/M level. That means you need to understand what the performance bottlenecks of your model are and treat those carefully, but for the most part you are freed to write the proper code to fit your model first.
@Hammet & Ayende: No arrogance meant with that statement (I'll buy you a beer sometime when we're in the same geographic location and hopefully you'll see that the last thing I am is arrogant) - so I'll rephrase and say that I wouldn't ever let an app go out the door without my stamp of approval as the architect. I think that's only good business.
Having said that - i'll also give you my opinion :). If i assigned one of my devs to create a page (webform) and it came back with 37 calls to the DB, I think i'd have a kitten. No, I'd have a cow. I'll be honest and say that if it wasn't you sitting across from me (I think you'd be MY boss actually) I'd send them packing. I've fired people for a lot less to be honest. Now for those who think I'd fire Oren for this - ummm no. I can just see that popping up somewhere.
But that's me. Jon Galloway says "performance is a feature" and to an extent I agree - you gotta get the concept out there. But at some level it also needs to be just "what we do". I've been in code reviews on < rev 4 and have been hammered for not using StringBuilders for crying out loud, and I would swear that some of the names above have written on the subject of StringBuilders and concatenation and performance - so why is it OK to use more connections than you should?
Fair enough, I would have hard time doing that either.
Oh my. I once was urgently called to a client because their application startup was issuing ~10,000 queries. Good luck that dinosaurs are
Why does everyone under duress about coding practices always say "why, if someone who worked for ME did that I would fire them _right away_".
That is the last refuge when you don't really have an argument, because I am damn sure you've done objectively worse code and not been fired for it (and will again in the future.)
But hey, if someone is doing it wrong and can't be trained, well then they probably shouldn't be doing this kind of work. I assume Rob meant to say something like "Well, if I had worked with the guy for a while and he hasn't been able to improve, I might have to let him go".
Rob
In case anyone ever reading this has the displeasure of working for the developer's version of Caligula, could you spell out these "instant firing offenses" for us. Since you have done it "for a lot less", could you give us an example? Was there a typo? Did they use an Async method when it should have been a Sync? The "Wrong" pattern? Have funny hair that day? Talked to you before coffee? RAaaaaRGH! Rob SMASH!
@Zan: Managing "Caligula Style" !!! I like it! Did you mean "Machiavelli"? I'll take Caligula ...
I had a developer scream at me, in front of the entire office and call me every name in the book because I told him to take a 15 minute break as he was driving the rest of the team nuts due to stress. He blamed me for every problem he had and was crying by the time he was done - and I then told him to go home. The next day I bought him lunch and we talked it through. This was 1996 and he's still a good friend.
I had another developer bring his hard drive to our office because he was working from home (1997) and wanted to bring the project in. As he was dismantling his work machine to install this drive I asked him why he didn't zip/ftp and he stared at me blankly. I had lunch with him too and suggested this wasn't the job for him.
Big difference here and as I tell my daughter "Some Can, Some Can't". It's up to the team leads to know the difference.
Now I know there must have been context to Oren's use of 32 (I was wrong RE 37) and I should consider that. But if he worked for me, I would have a very hard time with it - wouldn't you?
Caligula, duress, last refuge - krikey you make me sound like a flailing weenie. I give a lot to this community homey - you're out of line.
You were also called by your client to fix the 32 calls. I think you and I agree in that attacking performance straight off is not good. So yes I agree that you need to get it right.
To me, though, I lump calls to the DB into the "sensible" bucket. I prefer to not refactor unreasonable (i.e. > 32 queries) data access.
But I will concede that if it's just you, and it's how you work - well you could probably use a salami to type your code and it wouldn't matter. It's when you forget to wipe the keys off (or to refactor those 32 queries) that you get in trouble.
Comment preview