[H-GEN] Which is better?
Andrae Muys
andrae at tucanatech.com
Thu Apr 29 03:44:43 EDT 2004
Russell Stuart wrote:
> [ Humbug *General* list - semi-serious discussions about Humbug and ]
> [ Unix-related topics. Posts from non-subscribed addresses will vanish. ]
>
> On Wed, 2004-04-28 at 23:02, Andrae Muys wrote:
>
>>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.
>
> So I gave Harry a tip that would be helpful - beware that memory
> allocation in Java is not a cheap operation, like say i = i + 1. the
> "new" operator is not a VM op code - it is a function call, and a fairly
> expensive one at that. This statement is not contentious.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I boggle that you have the chuptza to suggest that the very subject of
our disagreement is 'not contentious'. Doubly so given I have already
posted one article stating the exact opposite.
> It is
> precisely why Java has a StringBuffer. StringBuffer's generally don't
> enhance readibility, usually the reverse in fact. But if you are going
> to build up a large String in Java, then good coding practice says you
> should use a StringBuffer.
>
Yes you should use StringBuffer; but once again you are mistaken in
attributing the problem to allocation. String appends are string
*appends*, the expensive part is *not* the allocation.
<SNIP example of expensive object *initialisation*>
> This is not contentious. Its also not about readability as both
> versions are equally readable, to me at least. And its not just about
> optimising loops. The advice "try to minimise memory allocation" does
> seem to cover it, though.
>
Your examples are disingenious. They use classes with expensive
initialisation, which swamp the allocation cost. If you had rather used
an immutable Point class your examples would at least be relevant to the
discussion.
class Point {
protected int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
My argument is that if you have a decent OO design, almost all of your
classes will resemble this in their simplicity; as such any examples of
the cost of heap allocation should be using such classes.
class BadExample {
public BadExample() {
Thread.sleep(3600000); // sleep for 1 hour.
}
}
Now 'new BadExample()' is going to take a really long time, but
suggesting that I should use
BadExample ex = new BadExample();
while (...) {
... use ex;
vs.
while (...) {
BadExample ex = new BadExample();
... use ex;
while correct, has *nothing* to do with the use of heap allocation
inside the loop! In the same manner, suggesting that doing extensive
memory-copying, or string-parsing (as per your two choices of example)
can be expensive provides *no* information regarding the relative cost
of a single heap allocation.[2]
> It does seem from the reactions I get on this list that to suggest
> someone should write reasonably optimal code is not politically correct
> in programming circles.
Ahh, so we finally reduce to ad hominem attacks. This isn't a matter of
'politically correct', it isn't a 'religious war', neither is it a
'subjective matter'. Java is designed and implemented to encourage and
support the extensive use of heap allocation. As a direct and
deliberate result of this design decision on the part of Gosling and
Steele, heap allocation simply is not sufficiently expensive to bother
with until a profiler flags it.
> God knows why. It is an essential part of the
> art of programming. Your have to strive to write readable and tight
> code.
And here we see the fundamental disconnect. I never strive to achieve
"readable and tight code"; on the contary I strive to achieve "correct
and readable code"[1]. I will actively avoid doing *anything* that
might compromise correctness or readability in the name of optimisation.
The only exception to this rule is to consider the complexity order of
any algorithm I choose, and even then I will try to take Kernighan and
Pike's advice: "try brute force first".
> It is often a trade off. There is no right answer; it takes
> experience just to get the balance right most of the time. Telling a
> new programmer to ignore optimisation entirely would make him get the
> balance wrong all of the time, if he followed the advice.
But that's the point. There is a right answer; nothing to "balance".
If they keep an eye on time and space complexity at the start, and
profile/optimise at the end; any effort expended trying to optimise in
the middle is not just useless, but actively harmful.
> Fortunately most don't. Most over optimise. This is not a bad thing.
> Just like bowling a cricket ball, your have to discover all the things
> that don't work, and you can only do that by trying them. So my advice
> to Harry would be to optimise to his hearts content. But do to try to
> measure the effect of what you have done - most of it won't be worth it.
Which is bad advice.
[0] For a definition of 'correct' that is sometimes rather loose.[1]
[1] See "Worse is Better" http://citeseer.ist.psu.edu/gabriel91lisp.html
[2] I have attached a benchmark demonstrating this. My measurements
indicate that a favourable comparison between string-append and heap
allocation shows a difference >5x. This is without any intervening
operations poluting the cache. I don't currently have the profiling
tools available to do a better job; but I would expect a fairer
comparison to favour heap allocation even more.
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: Looping.java
URL: <http://lists.humbug.org.au/pipermail/general/attachments/20040429/b74eb6e4/attachment.ksh>
More information about the General
mailing list