|
|
|||||||||||||||||||||||||||||||||||||||||||||
Osvaldo Pinali Doederlein's Blog
JavaFX Script tip: The Single Assignment per Method rule (and more)Posted by opinali on June 17, 2009 at 08:35 AM | Permalink | Comments (2)Property binding is a great feature of JavaFX Script, but it’s not without its issues, limitations or risks as you can see in recent posts. But even if perfect, no programming language feature exempts the programmer from learning how to use it optimally. There is an important rule that you must follow for binding. Check this code (simplified, from the JavaFX Balls benchmark):
What’s wrong here? I didn’t write the original version, but when I changed it (and introduced the problem), I was not fully aware of the consequences. The problem is that the properties _x and _y are assigned multiple times in the method. This is bad because these properties are bound elsewhere in the code:
When move() is invoked for some ball, the first thing it does is updating the _x and _y coordinates. These updates trigger binding notifications that force those bound expressions to be recomputed, changing the state of the ImageView nodes that are created by newBall() and included in the animation. But if the ball “hits” any border of the window, one or more of move()’s if statements will execute extra code that “bounces” the ball. The original code only changed the velocity variables _vx and _vy, but I decided to also adjust the coordinates so the balls wouldn’t be positioned in irregular positions (like negative coordinates) even for a single frame. But when move() executes a second assignment to _x, for example, all properties that are bound to _x will be notified and evaluated again. This is duplicate work that surely costs some CPU cycles. The solution is very simple: I only need to make sure that properties subject to binding are only assigned to at most once per method – the Single Assignment per Method (SAM) rule. This is easy to do with extra local variables:
In the new code, binding notifications and updates will only be triggered at the end, when the properties _x, _y are sync’ed with the temp variables newX, newY. The SAM rule is not really a new idea; it’s not even specific to JavaFX Script. I do this a lot in Java due to concurrency, to guarantee both consistency and performance: if I have to assign new values to shared fields and this is expensive enough so I don’t want to do everything in a big synchronized block, then I build the new values using temporary variables, and in the end I just assign the result to the field. With the extra bonus that, if it’s a single field to update (or there are no ordering issues), I don’t even need to synchronize the assignment step, so the code has zero locking overhead. I also follow the SAM rule for volatile fields even when the value computation is not expensive, because volatile writes are expensive. For really performance-critical stuff, I often obey the SAM rule even for common fields, because writing to any field is more expensive than to local variables, for two reasons: (a) local vars are typically allocated in registers so writes don’t require memory stores, (b) for reference-type fields, most modern GCs impose “write barriers” – extra code that must be executed when any heap pointer is updated. Last but not least, the SAM rule gives me a warm and fuzzy feeling of writing code closer to a “functional style”, because even when I have to program with mutable state, at least I avoid temporary states (that may even be invalid). I prefer that objects transition from a canonical state A (a method’s pre-condition) to a canonical state B (a method’s post-condition) in a single shot, without any intermediary states. This is also good for concurrent code in situations where eventual races can be tolerated, except if they’d cause an exception or other misbehavior due to a thread using an object that is in an invalid, intermediary state. Is the SAM rule good enough?Now let’s go back to my example. Pondering it more thoroughly, I could certainly make extra enhancements. For one thing, I could store _x and _y in a Point2D object, say _pos, then move() would end with a single field update… but my first instinct screamed: Don’t do that, because this would impose an extra object allocation per call to move(), and JavaFX Balls is a cross-language benchmark, and I don’t want to add any overheads (however small) that competing Bubblemark programs are not paying… but, would this change really make the program slower? The extra allocation surely has some cost, but on the other hand, I’m coalescing binding notifications. If I have a single _pos property to change, its update will produce a single binding notification that will “fix” the values of both the translateX and translateY properties from in the ball nodes. The reduced effort of binding propagation may save enough CPU cycles to compensate the extra allocation – or even more, resulting in a net optimization. This leads to a second rule, now specific to JavaFX Script: Minimize Updates to ‘Bindable’ Properties. The article Performance Improvement Techniques for JavaFX Applications already offers a short tip “Avoid Unreasonable Bindings”, and other authors have also warned against binding-happy code. So I’m just being more specific: binding is a great tool, and sometimes you can’t avoid it, but you can do make it lighter, e.g. by grouping a set of bindable properties in a single object that is updated wholesale and generates a single round of updates to bound properties. [P.S.: I haven’t yet validated the claim that this behavior will be any faster, or enough faster to compensate for some extra allocation – in JavaFX Balls those binding events are just insignificant to appear in the performance profile. Asserting this would require a special microbenchmark, maybe I’ll write it eventually.] I agree with others who pointed as a problem that in JavaFX Script, all visible properties are bindable; we could use a modifier like Fabrizio’s suggested unbindable that disallows binding to a specific property, or some other form of control. Even good IDE support would help – I’d love a code editor that could flag, with special syntax highlight, properties that are being used in some binding expression; a browsing operation to navigate from a property to all expressions bound to it; or special performance warnings (in a tool like Checkstyle or even in javafxc) for methods that break the SAM rule, or (horror!!) update bindable properties inside a loop. Such tools would easily flag the most severe, binding-related, performance bugs in JavaFX apps. An unbindable property could be compiled into leaner code, without the wrapper “location” objects introduced by javafxc. With the current language, my property declared as public var _x = 0.0 (with static type Float determined by inference) is compiled to a FloatVariable object (plus significant wrapping code for get/set and other things). This overhead apparently doesn’t exist for local variables, non-public variables that are not bound, and constants declared by def. Still, it’s significant overhead for all public var fields in your whole program; even in a best-case scenario where HotSpot optimizes out all boilerplate, the cost of extra memory allocation remains. So, a binding modifier would be a important optimization… even if it’s an “ugly” low-level optimization, much in the spirit of Java’s final modifier. But when a language moves two steps forward in abstraction, it’s often important to give developers some way to make at least one step backward in performance-critical code. There are also semantically valid usages of unbindable. Besides the problem discussed by Fabrizio’s blog, an API provider may want to enforce “binding direction” in complex object graphs where developers could easily get confused and bind things the wrong way… binding doesn’t tolerate cycles, try this code: var x:Integer = bind y; var y = bind x. . JavaFX Script as a general purpose language?Posted by opinali on June 11, 2009 at 11:46 AM | Permalink | Comments (35)Fabrizio says: “You'd have problems in forcing it to a broader scope than the one it has been designed for.” (i.e., GUIs) This may be true, but only because JavaFX Script is still a bit recent in both design and implementation. A few important features are still missing, some only not included due to time/resource constraints because the team’s priority is the features to make JavaFX a viable RIA platform. Now that the critical, let’s-cross-the-chasm release 1.2 is out, I hope there is more time for enhancements in the “general purpose” area… Like this: JFXC-642: Support for maps as a core language construct. One comment even says “We could really do with this for Marina [1.2] release”. Unfortunately they didn’t, but the bug is now scheduled “After Marina”, i.e. the next release; it’s one of the top RFEs in my wish list. JavaFX Script’s List-like sequences are great, but we really need a Map counterpart, complete with all sorts of high-level syntax sugar (from initialization to powerful comprehensions) and smart javafxc optimizations like flattening, tuning of implementation class choice, sizing, immutable/mutable transitions, conversion from/to compatible Java collections, and other tricks that are already implemented for sequences. With that and perhaps other few enhancements, JavaFX Script would become just as "complete" as other modern high-level OOPLs. JavaFX Script really could be a very viable candidate to the role of successor or companion to Java as a language for implementation of full Java applications. Consider this: The Java language has come to a dead-end. The community, apparently, cannot stomach any evolution that would introduce even minimal backwards-compatibility breaking. The full compatibility constraint (both source and binary) makes very hard to introduce any major feature without some big compromise in either functionality, complexity, or interoperability with legacy APIs. Too many people disliked the enhancements of J2SE 5 because of their compatibility compromises (not only generics but also most other features – e.g. the enhanced-for is a timid enhancement compared to JavaFX Script’s). Java SE 7 (ok, JDK 7, so far) is turning out another failure at evolution – Project Coin has nice enhancements, but it could also be renamed to Project Alms, because that’s what it is: a charity for the poor souls who insist programming in Java but starve for a more modern and productive language. Scala might be a great successor of Java. It’s reasonably Java-like, well integrated to Java and its libraries, “designed for the JVM”, static typed. On top of that, it adds an impressive amount of modernization like type inference, generics (without erasure), functional programming, pattern matching, Actors, and more. In a comment from Gilad Bracha, it’s a “tour de force of language design”. But Scala is also a significant learning curve to most Java hackers. It’s a complex language, even though it avoids any legacy tradeoff. And the Scala team is apparently not yet done with new features, now v2.8 will introduce continuations and more cool stuff. I fear very much that Scala may be doomed to the same fate of Haskell – a language that enchants geekdom with a very elegant design and even a great implementation, but ultimately serves only to influence future designs with more pragmatic constraints. In my dreams, Sun would pick a subset of Scala that any competent Java programmer could master over a weekend, rename it to something like Java 3, and be done with it for the next decade (experts could stick with the full Scala, and that would be a superset of Java 3 so the next migration, or Java/Scala interop, would be even easier). Groovy has become an impressive system (an even more amazing feat after recovering of a difficult start), but just like JRuby, Jython and others, it is a dynamic typed language. Most Java programmers will never trade Java for these languages. I don’t mean to open this debate here, but if the advocates of dynamic languages think they can turn the tables once their languages are more mature, with better frameworks, compilers, success cases etc., it’s not as simple as that. Many developers with a strong education on programming languages, OO and related subjects, have a firm, well-founded preference for static typing, and can only be convinced to move to languages with even more (or better) of that, like Scala. Speaking for myself, the single feature of dynamic languages that’s worth anything IMHO is powerful metaprogramming features (as more superficial features like “less typing for variable declarations” are largely obsolete in modern languages - with a “pure” typesystem, strong generics, and type inference). Well, nothing is perfect, and I’ll take the safety/performance/convenience of static typing over a MOP any day. (Optional static typing like Groovy’s doesn’t cut it, because I don’t see how this can go together with some modern features like advanced type inference.) OK, so I didn’t resist and I did open that debate just a little; but the point is, most developers prefer static typing; this just won’t change next week; and it’s not even a Java-specific trait resulting from Sun’s designs. Other dominant languages, from C/C++ to C#, SQL, and any decent XML-based language (with a strict schema), are all static typed; C# is also evolving in the same general direction of Scala. Having said all that, the Java platform is welcoming dynamic languages; as an advocate of Java[-the-platform] I am very enthusiastic and supportive of improvements from javax.script to invokedynamic and other enhancements in JDK 7. Some people prefer dynamic languages, we can agree to disagree, to each his own etc. – I even make limited use of those languages in niche needs. And the bottom line is, if these languages run great in the JVM, it’s a win-win for the whole ecosystem around Java. Now let’s close this digression and turn back to JavaFX Script. If you’re already up to speed with JavaFX programming (and you value higher-level languages even with some small tradeoff in performance or access to legacy APIs), what are your thoughts about using this language as a general replacement of Java? Let’s say, to program the persistent entities and business logic, packed in some Java EE EAR, ”behind” the GUI? Which features are missing? (Suppose, of course, that somebody will write lightweight and convenient JavaFX Script APIs wrapping all the Java SE/EE APIs you need; or perhaps even better APIs that take full advantage of JavaFX Script, ignoring old cruft.) Beyond a map type, my next obvious pick is Java’s Annotations, essential to support most modern SE/EE APIs – and that’s a pretty small change as javafxc could basically “pass” the annotations to the resulting Java artifacts. Notice that I’m not proposing that JavaFX Script can be a full replacement for Java; just a “higher-level companion” for application-level coding. it’s OK to need Java for “system-level” tasks, from stuff that needs low-level typesystem features for performance, to ugly APIs that may be impossible to make much simpler with a thin wrapper like the full extent of Java Reflection APIs. P.S.: JavaFX Script’s binding feature, its biggest claim to fame, is most certainly NOT a DSL-esque construct that’s “only good for GUIs”. If you think that, it's like thinking that “generics are only good for Collections” or “closures are only good for event handling plus a better foreach” (I’ve heard/read such opinions from many, many developers who have shallow knowledge of these features). Binding is a very general and powerful construct. It remembers me of my study of Constraint Satisfaction Programming while doing my MSc ten years ago. Binding is more limited than CSP, it just implements the facility of automatic propagation of dependent assignments (but it’s very good at that, including minimal reevaluation: e.g., x = bind y + f(z) doesn’t invoke f(z) again when only y changed; with sequence binding, only affected slices are recomputed). But this is already very powerful. Just like those pure and famous OO or functional languages that didn’t succeed in the real world, CSP didn’t enter so far in the mainstream. (To be fair they didn’t even try – only academic attempts were made, like Kaleidoscope – now completely forgotten). But this research influenced more traditional systems, like JavaFX Script, to make a more pragmatic “baby step” that is still extremely useful. First look at JavaFX 1.2, Part IIPosted by opinali on June 10, 2009 at 08:02 AM | Permalink | Comments (5)Check first part here. By just adding –server, I got the following results (standard runs, without removing the toolbar or any other tricks):
HotSpot Server is not adequate for internet deployments or client software: not included in the public JRE, bigger loading time, bigger memory footprint. Typical Server warmup behavior applies: the 16 Balls benchmark (for example) only reaches its maximum score after ~45s of execution. In a real application with a “normal” frame rate, Server might take even more time to fully optimize JavaFX, unless the lower fps is compensated by a more complex scene. But these results are surprising because I’d think that after JavaFX 1.2’s scene graph improvements, JavaFX Ball’s performance would already be dominated by native code (FX lays over a good chunk of native libs, from its own runtime and also Java2D’s accelerated pipelines). So, we can see interesting potential. Java code in the runtime is still very significant, and maybe the new Scene Graph code (and also Java2D) can be further optimized… Or replaced by even more native code. Sun has already abandoned the PureJava dogma for the JavaFX runtime (the Mobile runtime, apparently, is even more native), so I wouldn’t write that off. HotSpot’s JIT rules and all, it often delivers C-level code speed, but no bytecode/JIT technology will ever compete with native code for near-zero loading time and minimal memory usage. [The only reason why competitors like Flash has that split-second loading time is that its runtime is basically a monolithic blob of native code written in C/C++. Flash’s managed code (AS3) is not significantly better than Java in loading time, and is just as bad in resource usage and worse in execution performance. Just look at AIR applications, they are every bit as slow-loading and memory-hungry as Swing applets, because AIR’s frameworks are written in ActionScript.]
Another possibility is actually using HotSpot Server’s superior optimizations... how? Recent builds of HotSpot (in JDK 7 and JDK 6u10+) have a “tiered” execution mode that should combine the best of both worlds: fast startup and lean footprint because most methods are compiled by the Client JIT, but top performance as the really hot methods are (re)compiled by the Server JIT. If this works well, it’s another promise of an important boost to the performance of Java desktop software. You can try this with –server –XX:+TieredCompilation, but the implementation is incomplete. This recent OpenJDK thread says it’s “in the back burner”, apparently with no progress since Steve Goldman, the engineer who was doing it (and to whom we owe other things like the current x64 support), passed away one year ago. The JVM switch works, showing very different compile logs, but the performance is not there; it’s not significantly different than pure Server. Several bugs track this feature, and I hope we can get really done in JDK 7 but I think that won’t be for FCS as it’s clearly not a priority (release driver). Besides that, other improvements of JDK 7, remarkably the Jigsaw modularization, may further improve the loading time of JavaFX (and also Swing) applets. First look at JavaFX 1.2Posted by opinali on June 02, 2009 at 08:52 AM | Permalink | Comments (2)MigrationJavaFX 1.2 is not a fully backwards compatible release. There are language and API changes, and the compiled code is not binary compatible even for sources that still compiles without changes in the new version. Check Stephen Chin’s migration guide. This continues the trend of 1.1; it seems Sun is not yet caring too hard about backwards compatibility. “Legacy” JavaFX 1.0 and 1.1 apps will keep running because the JPI or JAWS will fetch the right runtime for them; the bad news is, if you have deployed some JavaFX app, you must at the very least recompile and redeploy if you want that your users benefit from the improved 1.2 runtime. Breaking backwards compatibility is not in the “spirit” of Java, or other Sun platforms. Sun is clearly using the opportunity, as JavaFX’s adoption by real-world projects is very small to date, to fix JavaFX’s early mistakes. But the platform must eventually stabilize, and it’s good to see that the number of breaking changes is really minimal for the language, although still significant for the APIs. For JavaFX Balls, the single source code fix that I had to do was adding an extra comma to obey the new javafxc rules (can’t write a sequence like [a b c] anymore). Then I proceeded to drop the Swing components in favor of the new JavaFX native controls (the picture below shows those new controls, with the default style). I started by deleting the “Swing” prefix, e.g. SwingToggleGroup –> ToggleGroup, etc. Surprisingly, that was 95% of the porting work; the only remaining compilation problem was because the new RadioButton component doesn’t have a action property. I guess I am supposed to bind stuff into its selected property; but with my code, that would spoil the MVC-like structure because I would have that binding inside the model class. Some refactoring could avoid that, but I was in a hurry so I just used the onMouseReleased event and everything worked even though it’s not very clean. Next problem is that when I run the program, every time some ball “hits” the top or left borders, this causes a weird bug. The ball movement algorithm allows balls to be temporarily positioned in negative coordinates, e.g. if the ball was at x=1 with a speed dx=–3, it would fall in x=–2 and only in the next keyframe it would bounce to a positive coordinate. Up to JavaFX 1.1 that was not a problem, a small piece of the ball would just be clipped off. But JavaFX 1.2 has a new default behavior that causes a Group’s boundsInParent to be adjusted, so no objects will have negative coordinates. I suppose this is a smart default that can do the right thing for many apps, but JavaFX Balls was not prepared for that, and the result is very weird:
The problem is more severe for large numbers of balls, because the movement algorithm is very dumb and will put balls on even more negative coordinates if they don’t have space to bounce back. In the picture above, the origin coordinate is the position of the “128 Image Balls, 321 fps” string; this show how much the bounding box was pushed to the bottom and right. I spent a few minutes looking at the javadocs (still very thin…) but I couldn’t figure out how to properly customize this behavior. So I worked around it with some extra code in the ball movement to force balls to bounce immediately, avoiding negative coordinates in the first place: // left
if (this._x < (model.walls.minX) and this._vx < 0) {
this._vx = -this._vx;
this._x += this._vx;
}
// top
if (this._y < (model.walls.minY) and this._vy < 0) {
this._vy = -this._vy;
this._y += this._vy;
}
Unfortunately this creates a very slight deviation from the other Bubblemark implementations, and for some reason a small bounds-related jitter remains; so I’ll welcome any tips to fix this more properly. If you want to help, get the updated sources here. This is the worst kind of backwards-compatibility breaking / migration: I can fix in seconds most changes documented by Stephen’s guide (even the change from MI to mixins is easy); but the problems that take more work are those that don’t cause a compilation failure… remarkably for a platform that is still very thinly documented. Another interesting change is the code that re-creates the balls after the user changes the rendering option (Image or Vector) or the ball count. Such actions would always produce a small “pause” because replacing a sequence of nodes bound to the Scene Graph is expensive (more than it should, which I reported as JFXC-2911: Whole-sequence replacement interacts badly with binding, unfortunately not fixed for JavaFX 1.2). So I used smarter code that does the minimum possible work: public var imageBalls = not useVector on replace { resetBalls(-1) }
public var N:Integer on replace oldN { resetBalls(oldN) }
function resetBalls (oldN: Integer) {
fpsTimer.stop();
if (oldN == -1)
balls = for (i in [1 .. N]) newBall()
else if (oldN > N)
delete balls[N - 1 ..<]
else if (oldN < N)
insert (for (i in [oldN ..< N]) newBall()) into balls;
startFPS();
}
Performance ResultsNow let’s move to the fun part. These are my preliminary results with this “beta” JavaFX Balls code, running on the JavaFX 1.2 runtime:
JavaFX 1.2 has a completely rewritten animation core, and it shows. When I evaluated JavaFX 1.0, I complained and cried and whined about the poor scalability of its SceneGraph package, with the conclusion that JavaFX would “stand no chance” to implement serious animations (e.g. for action games, except for clones of trivial 1970's hits like Pac-Man). But this is now past. The performance can be even bigger in a “pure” animation: I found that the controls are relatively heavyweight (even with caching). If I remove the control toolbar, I get 16 Balls @ 992fps (almost reaching the 1000fps cap), or 128 Balls @ 380fps. Even more interesting is CPU usage: the 16 Balls score consumed less than 1% CPU (Q6600), and even the 128 Balls score consumed only 16% CPU. So the program is clearly not constrained by CPU, but rather by other factors like timers or VRAM/DRAM bandwidth. These results compare very favorably with most other Bubblemark contenders (both Java and other platforms). The very best score that I’ve seen before was for PulpCore: it scores 16 Balls @ 410fps, but 128 Balls @ 90fps only; and both saturated a full CPU core (25% of a quad-core). I tested again other competitors (including Flash and Silverlight 2), and they are all much worse than JavaFX in either FPS or CPU usage (often both). The “Swing optimized” program is slightly better as it delivers 128 Balls @ 60fps [capped] with <1% CPU, and 512 Balls @ 32fps usage with 13% CPU. I tweaked JavaFX Balls (60fps cap and 512 Balls option) and it was almost as good, with 3% CPU for 128 Balls and 20% for 512. Now, the real champion seems to be another recent contender, LWJGL/Slick; that beast can do 128 Balls @ ~1600fps with 25% CPU (one full core); or alternatively, up to 256 Balls (there’s no 512 option) @ 75fps [VSync-capped] with 1% CPU. There’s nothing better than a raw OpenGL binding. Java2D and JavaFX are optimized to use OpenGL or Direct3D, but extra layers of APIs and abstractions will always have some price. Java2D will always be a little worse than something like LWJGL, and JavaFX will always be a little worse than plain Java2D. But I expect JavaFX to narrow the gap even further, as the Scene Graph engine is new in 1.2 and it surely has bottlenecks to optimize out, not to mention javafxc, runtime, and other APIs, which are all still relatively new. My verdict: You can now write a top-class 2D action game (or other programs with high-end animation) in JavaFX. Your performance will be second (but not a distant second) only to really low-level options like pure Java2D or OpenGL bindings, or a specialized package like the Slick game engine. But now, the convenience of JavaFX costs so few CPU cycles that nobody should care, except high-end action game developers. Last, but not least, Java totally smokes its most important RIA competitors, Flash and Silverlight. There are many other interesting performance aspects to see but don’t have time to measure now: Performance in Linux; Effects; Memory management (1.0/1.1 would severely cap the performance of some programs, like the SmokeParticles demo, due to excessive allocation from the scene graph). Loading time seems much better but I must check that objectively. Sun's new App Store is JavaFX basedPosted by opinali on May 19, 2009 at 03:18 AM | Permalink | Comments (6)Check it at Jonathan’s Blog. Now, a unified app store for all Java devices, from feature phones up to desktops, if well executed is something with great potential. I hope JavaFX 1.5 and the rest (first "real" JavaFX Mobile runtime, new Designer Tool, updated IDE plugins), also to be released at J1, are coming in great shape. Full JavaFX comming for Linux and SolarisPosted by opinali on May 11, 2009 at 08:38 AM | Permalink | Comments (10)I noticed that bug RT-3308: Media Support for Linux and Solaris was Resolved as Fixed a few days ago. The media support (which is mostly native code) is the major portability trouble in JavaFX, it’s the piece that was missing for Linux and Solaris. The bug was also marked as a Release Driver for v1.5. Too bad that nightlies are not available to the public, as the JavaFX Runtime project is still closed. But in a few weeks, when 1.5 is released with these ports and other major features like the native component package, some people will have to find other reasons to discredit JavaFX. But as we mention Linux and closed development, let me say that I expect Sun to put the complete runtime into an open source license, now at JavaOne’09 and not one day later. I was reviewing Sun’s statements on that issue and the most recent and official position comes from the FAQ, which is pretty disheartening – it basically promises that the pieces already open will continue to be open; for the rest, “Sun is committed to delivering enhancements to the JavaFX platform and to this end will continue internal development and reconcile key elements with the open source builds, with future releases of the JavaFX platform.” That doesn’t look any good… Rich Green stated very clearly in JavaOne’07 that “We plan to open-source all of JavaFX as we work through the program”, and Jeet Kaul also confirmed a few months ago that “We will put the core runtime out in the open over time.” Either the FAQ needs to be fixed, or Sun is lying to us big time. Hopefully that’s not the case, and Sun won’t be stupid enough to use some excuse to only fulfill the open source promise in 2010 or 2011, when it will be too late. Sun already screwed up by not opening the JDK years before; don’t do it again. Earth to Sun: competition with AIR and Silverlight 3 will be strong and you need all help you can find – and the best thing that can happen to JavaFX is being included in the default package repositories of popular Linux distros. JDK 6u14 almost ready at b05; Making Java load faster and lighterPosted by opinali on April 24, 2009 at 08:52 AM | Permalink | Comments (10)I previously reported the highlights of b01 and b02. Following that, b03 was another round of stabilization and small features: fixed some critical compiler2 (HotSpot Server) bugs; closed an important Java2D perf bug (XOR rendering); allowed JavaFX (and other advanced gfx runtimes) to do custom font hinting; allowed users to customize java.lang.Integer’s valueOf() cache (smells like a benchmark-oriented feature); optimized Nimbus’ initialization for JavaFX (perhaps also for Swing apps?); optimized StAX’s memory management (apparently big impact on XML messaging); and closed another round of minor plugin2/JAWS bugs. This build also introduced (in experimental stage) some important enhancements to the Treemap, HashMap and BigDecimal classes – apparently a joint Apache/Sun effort that was discussed for example in David Dagastine’s blog (and yes, Sun has finally released their improvements back to Harmony). Then b04 was a less exciting build with an important backport of G1 fixes, a critical Vista detection fix, and the final round of plugin2/JAWS bugs. Now b05 is even less interesting (great news: converging to FCS) with a bunch of Lazy Loading optimizations and nothing very important. I am very interested in anything that makes Java load faster and consume less resources, it’s perhaps the biggest challenge for Java in the desktop (with either JavaFX, Swing or whatever toolkit that’s dear to you). I compared the latest stable JRE (6u13) to 6u14b05 with my JavaFX Balls 2 benchmark. The test is very simple: launch the program as an application from the command line (javafx -verbose:class -classpath JavaFXBalls.jar javafxballs.MainDesktop), collect the classloading logs, sort and diff them. Result:
I understand why the JRE uses the security and SSL APIs, so I added –Xverify:none and voilà! Only 2922 classes loaded, another cut of 102 classes or 3,3% of the normal 6u14b05 number. But we can’t possibly get rid of this overhead for apps deployed over the net. But JavaFX apps can still get rid of further Swing dependencies. JavaFX needs some Swing classes, remarkably the core of Nimbus, I guess for such needs as desktop preferences (colors etc.), sharing low-level support to create a window, handling events etc. But Swing (or Nimbus) appears to have a styling framework that loads virtually all Swing component classes – I guess it’s building some kind of Map<component class, configuration data>. This could perhaps be done lazily. If JavaFX needs the same config data, I guess that repository could be refactored to not be hardwired to Swing classes. Just some wild guesses, I’m not familiar with the source code form either Swing or the JavaFX runtime, or even with the styling/theming facilities of either. Fixing this dependency could save almost 200 classes, another significant reduction of 6,6% of all classes loaded by the latest 6u14 build. Remember that these classes not only need to be loaded from the rt.jar, they must be linked, verified, some code executed in interpreted mode (static initializers), lots of metadata created to hang around in the heap forever…, even if they never get a single object instantiated or a single method invoked. And if you allow me to repeat my own comment from a previous blog, I would love the opinion of the Sun JDK developers and other JVM hackers who really understand this issue: A quasi-instant loading time (as well as better resource usage) is possible for JavaFX (and even for Swing), but I'm afraid if it depends on more radical JRE changes than Sun seems committed to do now. Some personal ideas: - Much better CDS;
The reason why Flash initializes instantly is that its runtime is a big blob of plain old C/C++ code, compiled to a efficient, monolithic piece of native code that the OS is able do load/link/relocate/init with light speed. Sun is right now optimizing in a higher level (like several lazy loading refactorings). They also promise that Jigsaw (in JDK 7) will further improve loading time, but I'm not holding my breath to see a sub-second startup (even warm start) of any nontrivial JavaFX applet (or Swing, for that matter) only with those improvements. Let's hope I'm proven wrong. Oracle and Sun: Some good news, and "praising the ponytail"Posted by opinali on April 24, 2009 at 08:23 AM | Permalink | Comments (1)First article: Oracle brass coax Sun troops with tough love. Some initial (although vague) commitments to the future of Sun technologies and products. Greatest news is that Java will remain an open platform. Bad news is that Sun's new cloud initiative may be uninteresting for Oracle. Best quote is about the hardware business: "We know a little bit more about hardware than people think because we have to port across all these product lines... it seems like we just build software and throw it over the wall, but it's not the way it works".
Second article: Sun: Let us now praise the ponytail. World+dog have been bashing the leadership from Jonathan Schwartz (and the company's entire strategy including massive adoption of open source) since Sun's stock tanked and never recovered, but this article (from an ex-Sun employee) provides a very good rebuttal. Best quote: "It's really the same challenge Sun posed to minicomputer makers in the 1980s with Unix. Most of those competitors were sold for scrap, not $7.4bn. The mighty SGI fetched just $25m recently". I must also agree with the conclusions. But I never worked for Sun and never hold any Sun stock (or any stock in fact), what do you think?
Oracle and JavaFX: Should I Stay or Should I Go?Posted by opinali on April 22, 2009 at 08:56 AM | Permalink | Comments (41)Most of Sun stuff will be very useful to Oracle. I can see a future where Oracle sells you a “complete solution” with Oracle Database and related products (Fusion etc.) running on top of the Solaris OS, Niagara or x64 hardware, a 7xx0 storage system, and also benefiting from virtualization tech from both Solaris and VirtualBox; having MySQL+InnoDB as an entry-level / community database as a strategy for upsell, etc. OpenOffice.org and ODF may contribute to some CMS product, or perhaps just to piss off Microsoft. ;-) Even NetBeans’ future is not guaranteed doom – I was initially worried about NB but thinking again, Oracle has yet to put major eggs in the ESF basket… sure they contributed some great stuff like EclipseLink, but where Oracle stands in the IDE wars? JDeveloper has yet to adopt any Eclipse runtime tech (even after daddy JBuilder did that), and JDeveloper is a total failure in the market anyway (except perhaps for consumers totally tied to Oracle products like Forms). SQL Developer seems to be more successful (I love it!), and although being much more recent product, they wrote it on top of the JDeveloper base and not Eclipse. Perhaps Oracle is not willing to put all their tooling strategy in the hands of IBM, which still controls 99% of the core Eclipse projects (the ESF brags a lot about open governance and community – but when some big, bluish corp walks away from a project, like the Visual Editor, the code sits there to rot without any community contributors picking it up). And as much as I love Eclipse, NetBeans kicks its arse in areas like Swing, Java ME, Web, learning curve, integration, and support for alternative languages which is now something very hot. The latest releases became competitive in the overall IDE functionality (code editor etc.), and the icing of the cake is that NetBeans is built on top of conventional Java frameworks (like Swing) so my wild guess is that Oracle could port whatever unique features of JDeveloper into NetBeans much easier than into Eclipse. But now let’s enter my real subject. What happens to JavaFX now? The acquisition happened in a very critical point in JavaFX’s evolution. Its development is still moving very fast – version 1.0 was a good Developer Release, 1.1 is better but still for a limited niche, and 1.5 is just around the corner and it’s the first release for “real world business apps” that need a decent component package (for one thing). Sun is also in a rush improving the deployment story (loading time etc.) with every update of both JavaFX and the JRE. But even if JavaFX has great potential, its actual adoption is still in early stages. It’s not too late in the game for somebody at Oracle to see that JavaFX is not something they are interested, it’s not yet a revenue stream, no big contracts to honor or customer base to please…, and just kill it. Making things worse, Sun has yet to make a full open source release of JavaFX, or a complete port for Linux (both essential to get some backing from the FOSS community) – so if Oracle kills it, it’s dead all all one can do is move over to Flex or Silverlight (or back to the dark ages [IMHO] of Swing). Having said that, some people believe that Oracle is the best thing that could happen to JavaFX. The reasoning is: Oracle is already a player in the desktop with their Oracle Forms, which current version supports Java Applets. Forms will obviously benefit from all recent enhancements from JDK 6u10+. But JavaFX could bring Forms to the next level, integrating RIA-class features. My ignorance of Forms is deep, but based on five minutes of research (looking at some sample code) it seems to be a high-level framework that mixes a little bit of Java with all sorts of Oracle stuff (PL/SQL and weird proprietary XML and binary resources), and supports rendering via both Java Applets and JSF with Oracle’s ADF extensions. Perhaps the Applet model can be integrated to JavaFX without significant impact on the small bit of Java code that Forms apps seem to need. This scenario is possible, but to me it seems like wishful thinking – perhaps ADF is the primary forms target and they’re planning to ditch the Applet model and either ignore the RIA trend or adopt something else (like Flash) because Oracle doesn’t really want to be a innovator in a non-core business like front-ends. The JIRA shows 40+ bugs fixed since April 20 so it seems that the acquisition news didn’t impact the team yet. Sun is supposed to continue as an independent company until the acquisition is completed sometime this summer - hopefully the end of this summer or even later ;-) so I guess their brave hackers can keep pouring their souls and talent into their current projects, even with more passion if there is uncertainty about its future. Sun just bundled JavaFX with the JDK – great move, but that was certainly planned long before the buyout. My guess is that the more JavaFX advances in quality and adoption over the next months, the higher chance that the new landlords will want (or be forced) to keep it. But I’m worried that the pre-acquisition conditions will immediately tie Sun’s hands in critical actions, for example to release any currently proprietary code under an open source license (it’s very likely that a full open release of JavaFX was planned for JavaOne: Sun committed to such release and J1 is the perfect time to do that). Or to make major deals (e.g. with carriers and handset makers to push JavaFX Mobile) that would have to be honored by Oracle. Let me then make a pledge to both Sun and Oracle: We need a clear direction and assurance of JavaFX’s future. Why should I keep investing time and effort in a platform that Oracle may soon bury - or keep as a proprietary and commercial product, which would also lose me? I’m a JavaFX enthusiast; just finished to write a big 3-part series on JavaFX for the Brazilian Java Magazine. I hate to dump FUD here, but let’s talk like grown men, my time is money and I’m halting my investment in JavaFX until I have some reason to believe that it won’t be wasted. |
July 2009
Search this blog:CategoriesCommunityJ2ME J2SE JavaOne JSR Open Source Performance Programming Virtual Machine Archives
June 2009 Recent EntriesJavaFX Script tip: The Single Assignment per Method rule (and more) JavaFX Script as a general purpose language? First look at JavaFX 1.2, Part II | ||||||||||||||||||||||||||||||||||||||||||||
|
|