Project Lambda: Java Language Specification draft
opinali at gmail.com
Thu Jan 28 14:14:49 PST 2010
2010/1/28 Reinier Zwitserloot <reinier at zwitserloot.com>
> They designed [swing], apparently with the assumption that polymorphism,
>> stack frames, code size, extra indirection of some design patterns, etc. are
>> all "nickel-and-dime issues" that wouldn't matter.
> You fantastically misunderstand the problems with the swing API. The
> complaints are about the _API_ - the way you build apps with it. Not about
> performance. Netbeans performs just fine and the API didn't change one whit.
> Yes, swing apps used to be slow. They fixed it, without removing any of the
> nickel and dime stuff. It would be annoying and complicated, from an API
> point of view, to state that list literals come in lots of varieties and
> have all these options. It would be far simpler if a list literal is always
> the same immutable structure, and if you need more/different features, you
> create a new list initialized with the list literal.
Swing performs well _now_, after a full decade of JVM&HW improvements. SWT
had near-native performance in 2001. And the current speed still comes with
a cost in size, loading time, JIT overheads. (I know this is not due only to
the factors I mention, but also to the lightweight-component architecture.
But those are important factors still.)
> Swing is actually an example of why your performance crusade is in fact
> wrong: It proves that high-level optimizations are the only ones that
> matter, and it also proves that making API simple and eliminate as many
> options and complications as possible is a good thing.
Unfortunately, most high-level optimizations are not possible in Swing -
these typically require structural changes, not possible in a white-box
framework that exposes too much of its internals as public APIs. So I bet
there was a ton of low-level opts instead - I'm not intimate with Swing's
sources, but I'm always reading sources of other JDK pieces and it is
SHOCK-FULL of "nickel-and-dime" opts, e.g. copying fields to local variables
to avoid repeated getfield's seems to be standard practice, as well as
manual hoisting of .length/.size() outside loops, etc. (I'm not claiming
that most of Swing's improvements came from such optimizations; the major
boost probably came from increased Java2D GPU acceleration. Once gain, just
not a great example.)
> my NetBeans compiles pretty fast too, indeed both compilers are now
>> I/O-constrained on any recent machine/JVM, so this is not anymore a good
>> case study.
> So, javac vs. ecj is no longer a good case study? Huh? No, it _IS_ a good
> case study, it is serious anecdotal avidence that that micro-optimization,
> which is what ecj has done, does not help performance any, and instead makes
> a dog of a code base that is such a drag on maintainability and flexiblity
> that eclipse is legendary for lagging behind new java features so much.
Here I won't dup Neal's reply.
> I'm still waiting on even one case study on your end that this micro
> optimization bullpuckey is worth screwing up language features for.
I never proposed that, I did explain my position but that's one of the parts
you chose to not reply.
> You, on the other hand, keeping saying, in elaborate overtures, "No, no,
>> they are important! Trust me, even though what I say goes against all common
>> knowledge and I have no proof or even a use case to back up what I say!".
I can provide microbenchmarks that show the impact of low-level opts, but
you'd just shout back the cliché "microbenchmaks are worthless". So please
let me explain (again). I agree that low-level opts may only provide
extremely small gains (a few nanoseconds or bytes). But they DO make a
difference when your program does that thing A LOT. For example, pick any
Java program that is maths-bound and uses float values (e.g. a renderer),
and replace float->double. You'll notice an important big drop in
performance. A more concrete example: the compressed-oops optimization in
Sun's and IBM's recent JVMs, which basically saves 4 bytes per reference
At best you can argue that we should leave low-level opts to the compiler,
not pollute our app code with that... but this is EXACTLY WHAT I WANT TO DO.
I want to use high-level language features like lambdas and collections,
without paying a price any higher than necessary. And I'm not proposing
major tradeoffs of functionality or syntax. (Very often, the major tradeoff
is extra effort in the language design, specification, and compiler
> Yeah that would add yet special case to learn (if you care for precise
>> behavior), but the current spec is already counter-intuitive because Java
>> developers quickly learn that indexed iteration of ArrayList and friends is
>> better than using an Iterator (and won't ever throw CCE!), then comes
>> enhanced-for and breaks this intuition.
> indexed iteration across an arraylist is better than using an iterator? I
> beg your pardon?
> Iterators don't HAVE to be fail-fast. There's extra logic in ArrayList and
> friends to make them fail-fast. someone back then (correctly, but a full
> discussion is beyond the scope of this thread) decided that fail-fast is
> worth it. If you want to turn this around and say that fail-fast is actively
> harmful compared to the standard 'who knows what's going to happen'
> behaviour of indexed access through an AL, that's your right, but you
> certainly can't do it by just saying that "It's better!" without backing
> this up!
If you desire fail-fast behavior, you can just use a standard for loop with
explicit Iterator. Now we can argue which priority should weight more -
performance or the protection of CCE. The enhanced-for supports primitive
arrays, and you can do a mess with a primitive array (cannot change its
structure, but can move elements around, including huge arraycopy
operations). Also, the fail-fast behavior has a very flexible/related spec
(check CCE's javadocs - there's a TON of caveats), and an implementation
that would simply ignore it everywhere would be just fine. In fact I would
gladly vote to make the fail-fast checks optional, guarded by JDK1.4
assertions so I could enable/disable them with -ea/-da; javac could also
avoid the enhanced-for optimization of RandomAccess collections with -g.
IT'S A FRIGGIN' DEBUGGING FEATURE. If treated as such, we could even make it
better with more extensive checking. (IBM once did such changes in their JDK
1.4.2 - and yeah it was great because it picked a bug in my app; OTOH it
sucked because the race was harmless and the CCE was screwing an app in
production inside a large bank. This impl change was uncompliant because the
CCE was being thrown by a method that doesn't document it as possible
behavior, so I reported this as a bug to the customer; IBM later removed
More information about the coin-dev