[H-GEN] Which is better?
Andrae Muys
andrae at internode.on.net
Wed Apr 28 09:02:01 EDT 2004
Russell Stuart wrote:
> For example, it probably isn't worth the effort to pause
> for a few seconds, and check if a statement like "i = j;" can be moved
> out of the loop, but it is worth you while to consider moving "i = new
> I();" out of a loop.
In every example so far I would be pulling up any junior programmer who
failed to pull the calculation out of the loop. However my reasoning
wouldn't have *anything* to do with performance. The key issue is
readability! I ask anyone still following this thread to consider: what
is the implication in performing *any* operation inside a loop? Surely
that it is dependant on the iteration of the loop? In which case
putting any invariant calculation inside the loop is lying to the
reader, and is only likely to confuse.
My number one rule when it comes to code is
"Help the reader reason about the code".
So if you see me write
while (condition(state)) {
variable = calculateValue(state);
useVariable(variable);
}
You can be sure that there are at least some iterations where
calculateValue() will return a different value; simply because if it
couldn't, I would have expressed it's intent to be invariant as
variable = calculateValue(state);
while (condition(state)) {
useVariable(variable);
}
(Of course I avoid the global state implied by both the above examples
like the plague, but I didn't want to stray too far from the examples
used thus far.)
> Or perhaps consider making the class "I" immutable
> so you don't have to make defensive copies.
Now this is a *very* important point. Immutability is a seriously
underused concept. One of the watershed days in my coding career was
when I realised that mutable state is always optional, and that there
are a number of advantages to foregoing it. Of course again, the
primary advantage is in supporting readability; to this performance once
again plays second fiddle --- then again in this I'm only agreeing with
your 'defensive copy' comment.
> Both you and Andrae then disagreed with that statement, aggressively. I
> am still not sure why.
Because it is premature-optimisation; knuth's quip[0] has lost none of
it's applicability. Java is intended to be an object-oriented language.
So it is optimised for 1000's of little encapsulated state-machines
sending 10,000's of messages to each other[2]. The language has
sufficient flexibility to do structured-programming; it can do
functional-programming (although lack of LCO[1] hurts here); it can do
dataflow if you are a real masochist. However all the above suffer from
the fact that the language fights against it. Of course those of you so
focused on trying to second-guess the implementors for a few extra
uSeconds of performance have a worse fate. The runtime is optimised to
support 1000's of LESM's, and except for a few special cases (which you
will discover in profiling) you will actually get better performance
writing OO code without regard for micro-optimisations.
Of course this is dispite the fact that most of your performance will be
obtained through watching the expected complexity bounds of your
algorithms, and within those bounds keeping an eye on your IO.
> For the record, I originally said that Harry's
> original optimisation wasn't worth doing. Still, it was interesting to
> investigate it, if for no other reason than to see if my gut feeling was
> right. It turned out that under 1.5.0 it was a total waste of time.
> Under 1.4.1 your mileage may vary.
>
Regarding the value of the loop investigation, I can only really point
to AJ and Adrian's replies.
>>1. Think through your design and choose appropriate algorithms.
>>2. Write clean maintainable code.
>>3. If the application isn't fast enough, profile it.
>>4. Fix the performance bottle necks.
>>5. Go to step 3.
>
> A fine recommendation, and I don't recall anyone arguing against it when
> others said similar things in this thread. Exactly what constitutes
> "clean maintainable code" is possibly the real subject of this debate.
>
Fine. Except of course that everytime someone tries to emphisise the
importance of readability, someone else seems to want to respond
"Readability is important, as long as you minimise heap allocation".
The sentiment is not only wrong, but seriously harmful. IF you are
doing OOP then heap allocation is background noise, not worth thinking
about. OTOH if you want to program Java, the whole language from design
to implementation will oppose any attempt to write use a different paradigm.
Andrae Muys
[0] For those not familiar with it "Premature-optimisation is the root
of all evil".
[1] Last Call Optimisation, there was a reasonably extensive dsig thread
on it a month or so ago.
[2] Ok, so my description is out by several orders of magnitude; it
reads better this way ;)
More information about the General
mailing list