Java Performance Urban Legends 632
An anonymous reader writes "Urban legends are kind of like mind viruses; even though we know they are probably not true, we often can't resist the urge to retell them (and thus infect other gullible "hosts") because they make for such good storytelling. Most urban legends have some basis in fact, which only makes them harder to stamp out. Unfortunately, many pointers and tips about Java performance tuning are a lot like urban legends -- someone, somewhere, passes on a "tip" that has (or had) some basis in fact, but through its continued retelling, has lost what truth it once contained. This article examines some of these urban performance legends and sets the record straight."
hmmm (Score:2)
Re:hmmm (Score:5, Funny)
No, you didn't. You misspelled it once; the second time is simply being consistent.
Misspelling it twice would be writing "optomizing" and "optomezing"
Re:hmmm (Score:2)
<sigh/>
As a matter of fact I am in the basement just now...To what extent does this exist in other languages? (Score:5, Interesting)
I remember in my Turbo Pascal programming days (heh) that a lot of people said that using Units would degrade performance. So I tried it both ways and it never really made a difference, for my applications anyways.
I'd say before taking someone's word for it on a performance enhancing technique, test it out. Because not everything you read is true, and not everything you read will apply to every environment or every application.
Re:To what extent does this exist in other languag (Score:2, Insightful)
Good advice. People sometimes seem to want to solve the problem before knowing what the problem statement is. While their actions may not degrade performance significantly, they often times do not help.
I've learned over time that everything is relative. There is no cut and dried right and wrong in a lot of cases, but degrees of both. The real answer depends on your need, and not all needs are the same.
Re:To what extent does this exist in other languag (Score:5, Interesting)
Probably lots. Everywhere.
As a crude approximation, 90% of the time is due to 10% of the code. Improving the "efficiency" of the 90% of the code that is responsible for only 10% of the time tends to be counter-productive. Of course there are no easy magic rules for how to improve the 10% of the code that is responsible for 90% of the time, or even identify exactly what that 10% really is.
What does work is to have a sense of how long things should take and find and cure whatever is taking much longer than it should.
Re:To what extent does this exist in other languag (Score:3, Informative)
To support this with some real numbers, a while ago I was profiling a C++ application I was writing. The application has ~200,000 lines of code, and was writing out ~3,000 values per second. This was not good enough, so I profiled, and carefully improved the "top scorer
Re:To what extent does this exist in other languag (Score:3, Interesting)
I think with respect to web programming, this is itself a myth. This rule of thumb seems to have reached the popular consciousness of developers in the 80s when desktop apps ruled. This was a time when each additional user adds a CPU. And it's true; in such a world, you don't worry about that other 90%. But when you have a fixed number CPUs shared by vastly more clients, you need to worry about more than just the 10% most offending cod
a lot (Score:5, Insightful)
There's quite a bit of other stuff like this out there as well.
Re:a lot (Score:3, Insightful)
Simple code is more future-proof (Score:3, Insightful)
Insignificant optimizations (Score:3, Interesting)
That's a good example of optimization tip that is "true" yet useless. Turbo Pascal used a 64K code segment for each unit, so function calls within the main program were "near" calls and function calls to another unit were "far" calls. Each far call made the code one byte bigger than each near
A few from C++ (Score:5, Insightful)
The C++ world is full of myths about what does and doesn't enhance performance. Amongst my favourites...
In each of these cases, there is some overhead involved if you actually use the language feature, but generally not otherwise with any recent compiler. However, those overheads are usually less than hand-crafting the equivalent functionality (e.g., long jumps, function look-up tables a la C) would incur. Furthermore, if you actually understand the implications of these features, you can keep the overhead way down. The next time I see someone criticise templates for code bloat, and then demonstrate in the next post that they've never come across templated wrappers for generic base classes, I'm going to have to lecture them. }:-)
On the flip side...
Most of these get much more credit than they deserve. The first is true often, but not always: it sometimes shafts the optimiser in many compilers. The second is not true with any recent compiler. The third is true sometimes, but not nearly as often as you might expect: optimisers miss many of the apparent (to humans) possibilities anyway, and spot some of the others with or without a const there.
As always, the rule of thumb is to write correct, maintainable code first, and then to use compiler-specific, profiler-induced hackery where (and only where) required. Whether you're writing a database or a graphic engine, this is pretty much always good advice.
Re:A few from C++ (Score:3, Insightful)
Well, yes, but then they're not really exceptional, are they? Exceptions aren't intended to replace break or if.
The point here is that just having exceptions in the language does not mean all your code runs slower. Contrary to oft-quoted opinion, the zero overhead principle does apply here with modern compilers.
My favorite Java UL... (Score:5, Funny)
k.
Java is Slow (Score:4, Funny)
Then why the hell is it so slow?
Re:Java is Slow (Score:5, Informative)
I've worked on two embedded projects using Java on low power (energy consumption/CPU performance both) platforms. Both projects had amazingly similar things happen. I stated up from, "Java is interpreted; it will be slower than the C code of the previous project on the platform, potentially significant."
The reply, "We don't care about performance."
Four months later... "Why the hell is your code so slow?"
Interpreted is as interpreted does.
The article is wrong (Score:5, Informative)
1: Synchronization.
This is slow. Really slow. And it just gets worse when you're running on dual or quad processor machines. StringBuffer is a major offender; in a lame attempt to save one object allocation, it uses a simple reference counting device which requires synchronization for operations as trivial as appending a character. Writing a simple UnsynchronizedStringBuffer gave a measurable performance boost.
2: Object creation
This is the real problem. GC is slow. GC on SMP machines is still really slow in JDK 1.3 -- maybe JDK 1.4 is better, my experience is a little out of date. By rewriting large chunks of code to create fewer objects (often by using arrays of primitives) we made it much faster -- close to twice as fast, if memory serves.
3: Immutable objects
Yes, these add to GC, and so are bad for performance. But not such a great evil, so long as you don't overuse them.
Funny that the article "debunks" these myths without figures, when our thorough measurements showed that the problems are real, and in our case would have killed our chances of meeting performance targets had we not found them and dealt with them.
Some bigger issues for server-side design: be careful how you use remote calls (such as RMI) and how you use persistence (such as JDO). But the small things, which the article seems to misrepresent, matter too.
Re:Java is Slow (Score:4, Funny)
Why, later, was Surak so slow?
It's because Surak has never written a line of Java in his life and simply trots out the same tired old message that he heard 4 years ago on Slashdot and repeats whenever Java comes up.
Surak is essentially regurgitating, inspite of JITs and JNIs actually writing pretty good machine code these days.
Suraks are slow. That's why people try to avoid hiring them.
Re:Java is Slow (Score:4, Insightful)
People don't generally write one-off small apps they intend to run hundreds of times a day in java. That's not what it's designed to do.
If you want to compare performance, do something real-like and have it run once in your two or so languages to get a base, and then run them a few thousand times. Something more like this:
http://www.bagley.org/~doug/shootout/
Re:Sure I remember... (Score:5, Insightful)
Not all programs have the same requirements. In most cases developer time is much more valuable than CPU time.
Stay as close to the CPU core as possible, but far enough away to be effective. C and C++ are the only languages that accomplish this role.
Ridiculous. Most good programming techniques are independent of language. If you can't develop effectively in anything but C or C++, then your "skillz" could use some work.
Think before you code.
Yes. Think whether the performance gained by using a low-level language is actually significant, and if so whether it offsets the increased development time and greater risk of uncontrolled failures (e.g. exploitable buffer overruns).
C is a fine language, and is often necessary. But it's a premature optimization to insist on always using it because of nebulous performance concerns.
Re:Sure I remember... (Score:3, Insightful)
Java is used for writing large-scale backend enterprise applications, not small command-line utilities. Nobody is suggesting it as a replacement for perl. With the programs Java is used for, startup time is irrelevant (since it's only started once) and a
The best tip (Score:5, Insightful)
"Save optimizations for situations where performance improvements are actually needed, and employ optimizations that will make a measurable difference."
-1, bloody obvious (Score:2, Funny)
1) become a journalist
2) use common sense and lots of bullshit
3)????
4) profit!
The missing step appears to be get an MBA and go into management
It doesn't help... (Score:5, Interesting)
...when one of the first issues of Java magazine published an article explaining the Java object runtime model, but made it little more than a FUD-filled advertisement. (What killed it for me: claiming that C++ vtbls are always, in every implementation, done as a huge array of function pointers inside each obvject. It wasn't a typo, either; they had glossy color diagrams that were equally deliberately false.)
I think Java's a decent language, but it invented nothing new. Every language feature had been done before, and without the need for marketing department bullshit.
Re:It doesn't help... (Score:5, Insightful)
One day, someone is going to come along with a really f'ing amazing language. Everyone will be talking about how great it is. And if you are lucky, it might have half the features that Lisp has had for ages.
Re:It doesn't help... (Score:3, Interesting)
It's there in String, isn't it? They declared it good enough for themselves, but not good enough for us.
Java's nothing new and exciting if you program in more languages than what the corporate world tells you is popular. They just had a marketing machine behind them.
Times change (Score:4, Interesting)
What the article said is true - JVMs have improved a lot. They are getting better and better, even today. My friend likes to fool around with all these little 3d demos in Java and even the latest JDK (1.4.2 beta) suddenly offers big performance boosts over the previous JDK. The fact that I refuse to ever use a beta Java SDK is another story, though...so I won't see those performance gains for a little while.
Re:Times change (Score:5, Interesting)
No matter what, there will always be applications that strain our machines to the cusp of their abilities. And there will always be things we want to do that our machines cannot handle. It's only by performance tuning that these tasks can go from impossible to possible.
If John Carmack was forced to program in Java, for example, Doom would only now be possible. And Doom III wouldn't be possible for many more years. Performance matters. Not always, but often.
Re:Times change (Score:5, Interesting)
Actually, carmack considered java for Quake 3, but decided against it because he was worried about the quality of JVMs (something he couldn't control). Not because of their speed. He's said on many occasions that optimization in game code isn't even important anymore, since the vast majority of the work is done by the CPU is code inside the video card driver. He's said that for quake 3, even doubling the speed of the game code would only give a 10% improvement in framerate.
Re:Times change (Score:3, Informative)
Re:Times change (Score:5, Informative)
Besides, modern day games use very little CPU compared to 3d accelleration on the card. You can get cross-platform games very easy with GL4Java. (A JNI binding to OpenGL that works on any operating system with OpenGL libraries.) I've seen games written this way that are very snappy, and run well under both linux and windows. I haven't tested them on Mac, but I'm sure they are fine there too.
If I were to write a game, Java would by my language of choice. Java's NIO networking architecture is quite brilliant. You wouldn't have to port the game to anything. It might take some work getting a JVM on a PS2 with OpenGL libraries, but If you can get linux running, I don't see how getting a VM on it could be so difficult.
Also, it would be neat if you could use the same CD to play the game on your PS2 as you did to play it on a PC. I'm sure such a game would have more appeal to the masses, not to mention saving lots of money on distributing the game. Runs on Linux, Windows, Mac, PS2, and XBox and will be multiplayer between each one of them. Get out your PC and play against your friend on the XBox.
I think Java will very soon show the mindless idiots that flame away on slashdot every day about how Java is slow that it really isn't slow any more. Sure there are still a few performance bottle-necks, but on the whole, Java is fast now, especially when compared to the future alternative of
Re:Times change (Score:3, Insightful)
I thought the rest of your comment was insightful, but .Net is a very new technology that, for sure, will improve markedly in terms of performance in the future. It is unfair to compare pre-release first version .Net with a mature implementation of Java. (I am a MS hater, but let's be fair.)
The Unreal engine is like this, but not in Java (Score:3, Informative)
Unreal, Unreal Tourmanent, Unreal 2 and UT2003 (as well as the numerous games using their engine - Deus Ex, Rune and so on) are mostly written in Unrealscript, an object-oriented language heavily inspired by Java.
Epic didn't use Java itself, although Tim Sweeney did consider it:
Re:Times change (Score:5, Interesting)
In those days, I hated Java and Macromedia Flash, because even then, they only used it to do the exact things a scripted mouseovers could reproduce. Those two programs accounted for most of the slowest web page loads...
Now I have a P4 1.5 GHz with gobs of RAM running XP, and I have a hard time running enough tasks to slow it down. With a cable modem, I don't care about huge binary applets. I guess Java just needed some hardware upgrades for it to become useable...
Java's memory usage (Score:2, Interesting)
Isn't the memory usage one of negatives of java?
While I don't care too much for java's wordy verbose syntax , anything that competes with Microsoft is A-OK in my book.
If any of you think Sun is making a ton of money on java , check this link out. [com.com]
I am beginning to feel sorry for SUN. They are also in some economic hard times laying off alot of people.
Re:Java's memory usage (Score:3, Insightful)
Re:Java's memory usage (Score:5, Insightful)
>efficient?
Well, java applications tend to use a whole lot of memory compared to C++, because of the way objects are allocated, and because there is no control over the details of allocation available to the programmer. Java Objects tend to be pretty heavy, partly because every Object carries a virtual table (to implement polymorphism, reflection, etc.) and also because every Object has the overhead required for the thread synchronization model.
As to whether or not it is "efficient", it depends on your point of view. For some applications, the java memory model is very efficient. Java goes to great lengths to ensure coherence among unsynchronized reads and writes in multiprocessor systems, and it must accomplish this via completely abstract means. Platform independence comes with a price, and a big part of that price is that high level optimizations become difficult or impossible to implement. JIT's and native libraries may help, but, there is still a hugely complex problem in exposing any sort of high level control of those things to the programmer. That is, in my opinion, the main reason that it is not fair to compare Java performance to C++ performance. It is not an apples-to-apples comparison. I think it would be reasonable to compare a transaction system written say, in J2EE under an app server, to say, a C++ transaction system running under an ORB. I think you will find that Java compares favorably in that context, and is simpler to write and maintain. I believe that makes it an excellent choice for business software.
If your model did not require threads and locks, for instance, you could do away with much of the complexity.
There is a whole heck of a lot going on under the hood to enable concurrent processing. You write your code as if it will execute sequentially, but there are many situations where operations will be interleaved, optimized to execute out-of-order (or even optimized away entirely).
The java implementation is much more concerned with Visibility, Atomicity, and Ordering, than it is with raw performance. If you really want to learn how it works, the specification is not a difficult read. Most of the details about memory are here:
http://java.sun.com/docs/books/jls/second_editi
Re:Java's memory usage (Score:3, Informative)
Java Objects tend to be pretty heavy, partly because every Object carries a virtual table (to implement polymorphism, reflection, etc.) (...)
Maybe this is how urban myths come into life?
An object in java does not have a 'virtual table'; a class has a table with method pointers, an instance of that class does not. One could say that "the method table is static". It would be very foolish to have x exact copies of a method table for x instances of the same class.
Urban MySQL vs. Urban PostgreSQL (Score:5, Interesting)
And I'm sure MySQL DBAs all know PostgreSQL is slow, bloated, and is only good for huge database rollouts.
Except, well. You get the gist. I'm replying to this article because I now know first-hand that both camps are getting a lot of it wrong.
I've written up what began as a final in-depth studied proof that MySQL wasn't ready for the corporate environment (because I'm a PostgreSQL guy, see?) but ended up reluctantly having to conclude MySQL is slightly more ready for the corporate environment than PostgreSQL!
The writeup [faemalia.org] is on a wiki, so feel free to register and add your own experience. Please be ready to back up your opinions with facts.
Re:Urban MySQL vs. Urban PostgreSQL (Score:2)
Does this mean Windows doesn't crash?
Wow... My eyes have been k#dK%SDJ3(&s*x@M NO CARRIER
Absolut no content (Score:2, Insightful)
And about the strings example:
If you want't to prove that the Immutable string class is not slow the right way to do it is to make a program that make a lot of string operations and then compare the speed with one of the non Immutable string classes for java that
Re:Absolut no content (Score:2)
I actuelly tried to run the benchmark
Synchronized took 213 ms
Unsynchronized took 22 ms
So you can conclude that calling a synchronized function is 10 times as slow, as calling one that is NOT syncrhonized. But this does NOT matter because the actuell time it take to call a synchronized method is so small. It calls
the synchronized method 10000000 times in ~200 meaning that you can call a synchronized method 50000 times each ms(If you already got the lock)
So in any real program the work do
Re:Absolut no content (Score:2)
Antidote (Score:4, Insightful)
Here's a bit of an antidote: Why Java will always be slower than C++ [jelovic.com]
Re:Antidote (Score:3, Interesting)
This issue is debatable. The example the author gives is a bad one.
What small objects? For me these are iterators. I use a lot of them in my designs. Someone else may use complex numbers. A 3D programmer may use a vector or a point class. People dealing with time series data will use a time class. Anybody using these will definitely hate trading a zero-time stack allocation for a constant-time heap allocation. Put that in a loop and that becomes O (n) vs. zer
Re:Antidote (Score:5, Insightful)
People dealing with time series data will use a time class. Anybody using these will definitely hate trading a zero-time stack allocation for a constant-time heap allocation. Put that in a loop and that becomes O (n) vs. zero. Add another loop and you get O (n^2) vs. again, zero.
What? A constant time operation in an 'n' loop is O(n), but then again, the loop is O(n) to start with. Add another loop and you get O(n^2) versus O(n^2). The constant of proportionality has changed, but that's all. If you were using C++, you'd probably call a constructor and possibly destructor anyway; so the difference is not nearly as much as you'd expect; and java heap allocation is only about 3 instructions anyway on a decent VM. This article is total junk.
Re:Antidote (Score:5, Insightful)
My favorite was the cast issue. He fails to recognize that the code he is talking about is run once, then it is a static cast just like most people use in C++. Something that must by dynamically casted at runtime, on the other hand, will be much faster in Java since it doesn't have to figure out the casting for an object every time you cast. It basically does it once, then it will be able to cast any object of the same time to the same casted type as before.
It's complete idiocy by a person who hasn't spent any significant time using Java.
If you want to critisize Java you must:
A: target memory usage, site a specific API and why in your OPINION you don't like it, or target startup time.
B: have not used C++ techniques of optimization on Java
C: have tried the latest JVM.
D: have checked the bug parade, and found that the issue you are talking about is not currently being fixed or has been in the bug parade for a very long time.
If you don't follow all those, then you are really just taking pot shots at a system that works quite well for a LOT of people. I've never met anyone that didn't like Java after they played with it for a while (except back before 1.3).
There is a SSH server written in Java now that supports all the features that OpenSSh does... I think I'm going to give it a try... no more CRC buffer overflows for me.
Re:Antidote (Score:3, Insightful)
Java does virtual method inlining. That, alone, makes it potentially faster than C++. A slightly more intelligent garbage collector designed to decrease page-faults later, and presto, C++ is the slow language.
[Note that Garbage Collection can't scale very well on multiple CPU machines, so Java still won't be the be-all-and-end-all language unless it divides its objects into seperate "
Java not always slower (Score:5, Insightful)
Try writing a simple recursive Fibonacci number calculator in both C++ and Java. The Java one is faster, when using a JIT enabled JVM. Of course, that is a contrived example, but it shows that just-in-time compiling can be faster.
Re:Java not always slower (Score:3, Interesting)
I tried the simple and stupid
int fib(int i) {
if(i<=2) return 1;
else return fib(i-1)+fib(i-2);
}
without optimization on javac and gcc (the latter was slowed down by it so I figured it wouldn't be fair). Calculating up to 45 on my P3 800MHz took, according to 'time', 1m5.554s. Java used 0m51.807s (and that's including the jvm loading).
Pretty neat.
java -Xint (no JIT) is still running though.
Re:Antidote (Score:3, Insightful)
errr...
Saying "Java will always be slower than C++" is like saying that there will always be less graduate students than undergraduates. Java and C++ live in the same Von Neumann-ian world, but C++ is allowed to muck with pointers, and Java isn't. Moreover Java has garbage collection.
However, I dare say that the time that a programmer saves by not mucking around with pointers is far more valuable than the time saved by typical C++ optimization. This may not hold true in performance-critical domains (
Re:Antidote (Score:3, Insightful)
Welcome to the world of optimizing compilers and runtimes! Both things can actually help application performance, because they allow the language implementation to do smart things.
For example, some implementations of malloc() have
Java is slow (Score:3, Interesting)
If there is an "inner loop" of your application that needs performance above all else, and you need to program it in Java for whatever reason, there are two things you should get rid of:
I've just found that you can't trust the garbage collector, no matter how good people say it is. People have been saying it's great since the beginning of Java, and now they say, "It wasn't good before, but it is now." And they'll be saying the same thing in 3 more years. No matter what, the opportunistic garbage collection of C/C++ simply leads to better performance than any language that tries to do the garbage collection for you.
Re:Java is slow (Score:5, Informative)
I've used Java on embedded applications, on systems that create lots, and lots of objects. And I don't recall ever running out of memory, if there wasn't a bug in the Java program.
But I'm not saying you're lying or wrong, only that a well tuned, well supported, JVM doesn't do this.
the opportunistic garbage collection of C/C++ simply leads to better performance than any language that tries to do the garbage collection for you.
What opportunistic garbage collection of C/C++? You mean delete and free? Get real! Personally, I wouldn't trust the average programmer to even collect garbage correctly more than half the time, and that doesn't cut it. I've had way, way less problems with Java GC than I've ever had with C/C++ in a realtime system. People have spent weeks finding memory leaks; and one time a leak I found was a ghastly C++ compiler bug where the compiler screwed up the automatic destructors on unnamed objects.
Re:Java is slow (Score:3, Insightful)
There is a difference between using up all your memory and running out of memory. Java maxes out the memory that it's allowed to take in the circumstances I was talking about.
Suppose you have a tight loop that c
Re:Java is slow (Score:3, Interesting)
Simpler? Sure, if you have just a few objects. But with a lot of objects, it's much, much, much more complicated. As anybody who has spent hours running down a malloc/free error in somebody else's code can tell you.
If you can't use new and delete or free and malloc correctly, then there's probably a lot of other things you can't do well either.
Welcome to the human condition.
Re:Java is slow (Score:4, Informative)
Re:Java is slow (Score:2)
What you lose by taking up free memory is the potential for needed operations. For example, your JVM won't know that your browser needs more memory to allocate that huge PDF. Ideally, it should realize that your waiting for memory and start getting agressive about garbage collecting. But it doesn't know this. Instead, the operating system starts swapping stuff out to disk, making everything slow.
I
Re:Java is slow (Score:5, Informative)
while(true)
{
Object o = new Object();
o = null;
}
The GC won't free the memory in realtime (or, sometimes, ever), as would be the case for C++/C with new/delete malloc/free.
Re:Java is slow (Score:3, Interesting)
I said you can control the initial size of the memory. Many JVMs will normally not go outside that size unless it has already GCd and it still doesn't have enough memory.
I should be able to tell the GC that I am done with an object right here and now, rather than waiting for the low priority GC thread to take too long to pick it up.
Yes, that would certainly be useful; however, you can usually (depending on t
Ok, so if Java doesn't suck speed wise.. (Score:3, Funny)
*looks at Limewire*
*looks at administration applets written by Sun which don't work over X11*
jav vm sucks (Score:2, Interesting)
Fact: Valenz and Leopold did a survey (summarrixed in the most recent issue of Dr Dobbs) whereby Java bytecode programs were converted to MSIL, and the .NET, Rotor, MONO, Sun, Blackdown, etc. VMs were compared. In each case, Microsoft's .NET VM had a 5-20% speed increase over the best java VM, and even the MONO and Rotor VMs had a 2-15% spee
Performance is ok, but memory footprint... (Score:4, Interesting)
javaw.exe - Mem usage 70,244K
java.exe - Mem usage 9,808K
According to task manager. Granted, now I got 512 to take from but it's still eating up much more memory than anything else.
Kjella
kind of right, and that's a problem (Score:3, Insightful)
But that's not really a good thing. Sun pushed on the JIT on the theory that that would address performance problems. It didn't. The Perl and Python runtimes are much slower than Java's, but Perl and Python applications generally start up much faster and are considerably more responsive.
Java is as sluggish as ever, and more bloated than it has ever been. What is really responsible for Java's poor performance for real-world applications is its class loading, memory footprint, and just plain awful library design and implementation.
Profile your software, don't guess (Score:2, Insightful)
Error in title (Score:3, Funny)
Bullshit (Score:3, Insightful)
Let's take them one by one:
<br>
<LI> Final methods and classes - when you call a final method from the same class you save a lookup in the virtual method table (there is no doubt about what method is going to be called, as it couldn't have been overwritten in a descendent), and furthermore you can inline that method. On a "stupid" JVM (read: from Sun) you won't see any difference, on an optimized one you will.
<LI> Synchronization can become a bottleneck on SMP systems, because it implies cache synchronization (exiting a synchronized block
is a memory barrier) - you clearly aren't going to see it on a single processor. But not using synchronization is just as bad (you should use synchronization with <b>all</b> variables that are shared, because you do want memory barriers for correctness)
<LI> Immutable objects - this one clearly depends on the garbage collector that you use.
<p>
Conclusion: the performance of these tricks depend on two things - your JVM and Amdahl's law (how often are these improvements going to manifest themselves)
<p>
Re:Bullshit (Score:3, Insightful)
You don't appear to know much about synchronization in Java.
Take your first example. Synchronized methods obtain locks on the object this (or the Class object in the case of static methods), not on the variable referenced therein. If bar() is called while foo() is executing, bar() will not begin executing until foo() finishes. If this were the only synchronized code in a program, it would not be possible for that program to deadlock. However, Java does not find or break deadlocks.
Your second example i
Worst...disproof...ever (Score:5, Informative)
Yeah. Lets look at this article:
Myth 1: Synchronization Is Really Slow
a) Ummm, well it was slow...but not anymore!
b) As the programmer, you have no idea what code is eventually going to be run. (Who knows! It might be FAST!)
c) Who cares about the actual numbers; it's only a constant overhead! (This is actually a good point -- the sync'd method isn't doing anything, so the syncing can't amortize its penalty across any amount of work. But...still..."regardless of the actual numbers"?!?)
d) But...but...you need to sync! Your programs will crash if you don't!
Myth 2: Declaring methods "final" speeds them up
a) Nuh-uh!
b) I don't see a benchmark anywhere! (Nor, apparently, can I write one.)
c) But...but...what if someone wants to extend your class?
Myth 3: Immutable Objects are bad for performance
a) It could be faster. It could be slower. Maybe you won't be able to detect a difference.
b) The myth comes from a fundamental truth about how Java does many things really really slowly.
c) StringBuffer creates objects too...ummm...in the corner case where the default buffer size isn't big enough to handle the added data, and the buffer wasn't preconfigured to store sufficient amount of data...heh! Look over there! *runs away*
d) As the programmer, you have no idea what the garbage collector is eventually going to do. (Who knows! It might be FAST!)
e) But...but...you're sacrificing object oriented principals!
I was really waiitng for Myth 4..."Who needs performance! It's a Multi-Gigahertz PAHHHTAY!!!" But apparently that got cut.
I've got a data point for 'em. You know Nokia's n-Gage Gameboy Killer? Hehhehe. Not _only_ did they completely forget to throw in any hardware acceleration for sprites -- heh, an ARM is fast enough -- but it looks like you're supposed to write games in Java.
So, yeah. Puzzle Bobble @ 5fps. But I'm sure it's very elegant code
--Dan
P.S. On the flip side, I'm playing with an app whose 2D GUI was designed with GL4Java...it's a work of art; faster than Win32, at least for tree manipulation. Java can be a beautiful language once its relieved of the duty of actually computing anything...
Truth AND Consequences (Score:5, Interesting)
What's sloppy about the article? Well first of all, Goetz asserts " even though we know they are probably not true, we often can't resist the urge to retell [urban legends]". Where in Hades did he get such a silly idea? Some half-remembered sociology book? Everybody who's ever told me an urban legend really believed in that exploding microwave poodle or the dead construction workers concealed in Hoover Dam. I myself remember feeling rather peeved when I heard the sewer alligator legend debunked.
Second, perfomance myths are not "urban legends". ULs are third-hand stories that are difficult to debunk because the actual facts are hard to get at. "Facts" that people can check but don't are just myths or folklore.
Anyway, here's my favorite performance myth: "more is faster". The most common variation of this is "application performance is a function of CPU speed". Ironically enough, I encountered this one when I was working at JavaSoft. Part of my job was to run JavaDoc against the source code to generate the API docs. The guy who did it before me ran it on a workstation, where a run took about 10 hours. Neither of us had the engineering background to really understand why this took so long. He just took for granted that it was a matter of CPU cycles. I knew a little more than him -- not enough to understand what was actually going on, but enough to be skeptical of his explanation.
Eventually, I put together the relevent facts: (1) JavaDoc loads class files to gain API data, using the object introspection feature; (2) the Java VM we were using visited every loaded class frequently, because of a primitive garbage collection engine; (3) forcing a lot of Java classes into memory is a good way to defeat your computer's virtual memory feature...
Eureka! I tried doing the JavaDoc run on a machine with enough RAM to prevent swapping. Run went from 10 hours to 10 minutes.
Another variation of this myth is "interpreted code is slower than native code". That bit of folklore has hurt Java no end. If your application is CPU-bound, you might get a performance boost by using native code. But, with the obvious exception of FPS games, how many apps are CPU bound?
Here's another variation: "I/O performance is directly proportional to buffer size". At another hardware vendor I worked for, one of our customers actually filed a bug because his I/O-bound application actually got slower when he used buffer sizes greater than 2 meg. It was not, of course, a coincidence that 2 meg was also the CPU cache size!
Re:Truth AND Consequences (Score:3, Interesting)
For example, we recently "tuned" our transaction engine to the extent that it was truly CPU bound in a multiple tiered architecture with hundreds of rem
Yeah but... (Score:5, Insightful)
However, what I really dig is the library. Sockets, Strings, half a billion data structures, numeric and currency formatting, Internationalization and Localiztion support....
And there's always the JNI if I need to optimize in C.
Not to mention servlets, JSP's and JDBC.
You gotta' admid that this is all great stuff. So for certain applications (specially on the server) the benefits of the library far outweigh the performance problems of the sandbox.
Yeah, C++ has a great library too. But the Java library is so damned easy to use.
Seductive the dark side is.....
Re:Yeah but... (Score:5, Insightful)
Re:Yeah but... (Score:3, Insightful)
This is another false statement. Unless you pass more bytes than the buffer really holds in the 'recv' function, you don't have to bounds-check anything. Because the operating system makes sure the received data fit on the given buffer. So, BSD sockets don't require bounds checking, but what you do with the data after that may do.
He's saying that it's impossible to write buffer over
What about numerics (Score:3, Interesting)
I notice that while the article mentioned deals with a couple of nit-picky optimizations, it doesn't tell us anything useful about how to make Java rock on the numerics, which is the pace performance matters most to me. For instance, how would you write FFTW in Java?
Re:What about numerics (Score:3, Informative)
They're open source libraries for high performance scientific computing in Java and fairly easy to use at that.
Bigger synchronization myths (Score:5, Insightful)
However, the article perpetuates another myth: "Synchronization should be easy. The more things you synchronize, the better off you are."
My hard experience says otherwise. First off, making multithreaded programs work correctly is very hard. Therefore, multiple threads should be avoided if at all possible. You can avoid a lot of these problems in many cases if you use a function like "select()" in a single-threaded program (which, IIRC, Java unfortunately doesn't support). Even though it looks harder to program, it ends up being easier to debug.
However, sometimes you just can't avoid threads. IMHO, adding "synchronize" as a language keword and encouraging easy creation of threads was a mistake. That doesn't begin to solve your problems. For example, it does nothing to help you avoid deadlocks. In fact, sprinkling synchronized blocks around your program is a recipe for deadlocks and unexpected timing-dependent buggy behavior.
If you must use multiple threads, there should be one main thread that runs almost all of the program's logic, and a set of highly constrained, carefully controlled worker threads. These threads should not interact with any other (mutable) data structures in the program. Ideally, there should be at most two synchronization points in the program: a work queue and a results queue. The elements of these queues should package up all of the state needed for a worker thread to solve a piece of a problem or deliver its results.
With an approach like this that has minimal synchronization, there's no need to add a keyword to the language or put synchronization into many library container classes. And of course, performance is hardly an issue at all when you only synchronize twice per worker thread run.
Why do poor coders have tunnel vision? (Score:5, Insightful)
Yes, if I need speed, I use C, the same as anyone else. If I am writing a Web application, I use Java. That's an area where Java excels. And maybe I'll get lucky enough to be able to code a project in Assembly or Lisp, who knows? Programming does not follow the "jack of all trades, expert at none" theory. General concepts map well across the spectrum.
I find it discouraging that there are so many programmers who only want to learn as much about their job, as to merely be good enough . Don't they feel any pride, or any desire to excel at something?
Coders who can only handle one language should be paid minimum wage; that is all they are worth. That is because it is neither the language nor the implementation that is important. It is the knowledge of how to program which will ensure your career and pay your bills.
Re:Why do poor coders have tunnel vision? (Score:3, Interesting)
Java offers two main advantages: a beefy class librar
Re:Why do poor coders have tunnel vision? (Score:4, Informative)
Not me. There are some *fast* functional programming language compilers out there. I've ported some of my log processors from python to OCaml, scheme (for the bigloo compiler) and C. The OCaml and bigloo compiled versions were almost exactly the same speed, and only slightly slower than the C version. The C version took me a *LOT* longer to write due to the difficulty of expressing what I was trying to do in C and making sure it was doing it safely.
In general, I agree with you, but I make great efforts to avoid C, as I am one of those who believe that C is inappropriate for almost every task for which it's used today (even some of the ones for which I'm using it).
Hardware manufacturers want slow software. (Score:3, Funny)
It was somewhat shocking to me, but back in the VAX days I learned that software made by hardware manufacturers is as slow as they can get the customer to accept. That makes customers buy more hardware.
Following the theme of naming products after food items, Sun's next software product is "Molasses".
If customers accept Molasses, the next January they will release an upgrade called "Molasses in January". The following product will break the naming tradition: It will be a run-anywhere language called "The check is in the mail". After that, there is "When pigs fly", and "When hell freezes".
The big question in the computing world is how not to become a dog on some manufacturer's leash. Woof, woof, where do you want me to go today, Bill, Steve, or Scott?
Why It's Still Slow, and What to Do (Score:5, Informative)
One of the reasons is that interactions with caches are hard to model, making it hard to know what to do to minimize problems. Caching is, inherently, a deal with the devil: you get speed but lose understanding. Sometimes you lose the speed too. Even when you understand, there's not much you can do. Sometimes complicated stuff is inherently expensive.
When I say caching, I mean not just CPU caches of RAM, but also RAM caches of (potentially swapped-out) process space. If you allow a naive garbage-collector to operate freely, it will happily consume the entire address space available, typically the sum of available RAM and swap space, before garbage-collecting, so the process will run not from RAM but from swap. When it garbage-collects, too, it has to walk a lot of that memory, and swap it all in.
Just running "ulimit -d" in the shell where the java (or other GC-language) program runs can help a lot. It will GC a lot more often, but if nothing is swapped out, the GC happens a lot faster, and the program's regular execution doesn't have to touch swapped-out pages. You have to know a lot about the program and the data it uses to guess the right ulimit value, and if you guess wrong the program fails, but a thousand-fold speed improvement earns a lot of forgiveness.
Did you really believe garbage collection would mean you don't have to know about memory management? It makes memory management harder, because the problem remains but there's less you can do about it. (For trivial programs it doesn't matter. If you only write trivial programs, though, you might as well find some other job.)
There's a similar effect with the CPU cache and RAM. Ideally you want the program code and the data it operates on all to live in cache, because touching the RAM takes 100 times as long at touching cache. With bytecodes, you have a lot more "cache pressure" -- you have the bytecodes themselves, the just-in-time compiler, and the native code it generates. At the same time, since your memory manager generally can't re-use memory that you just freed, it allocates other memory that, when touched, pushes out something else that was useful (such as program code).
The result is that no matter how clever the JVM is, there's not much it can do to get the performance of real programs close to optimal, or even within a pleasing fraction of equivalent C++ code. This despite all the toy benchmarks that seem to prove otherwise, and which carefully avoid all these real-world problems.
Of all the promised features of Java (like Lisp before it and C# after it), we're left with the sole remaining feature, that its virtual machine specifies precisely (or abstracts away) enough details of the runtime environment that the code is more portable than a faster native implementation, and the code might get written faster for the author having avoided thinking about details that affect performance.
The sole saving grace is that most programs don't have much need to run very fast anyway, or if they do it's hard to prove that they ought to run faster. Most people take what they get without complaining, or without complaining to anybody who cares, or without doing anything to make whoever is responsible uncomfortable enough to have to do anything differently. A whole generation trained to accept programs that crash daily or hourly is thrilled to find a program whose biggest problem is that they suspect it might be sluggish.
White coats, step right this way... (Score:3, Informative)
1) Re: swapping. Java memory management will always be superior to that of the OS - OS constraints should never be greater than those applied by the VM. The memory limit of a Java process is defined with the -Xmx=nnn parameter. For production use, this should nev
Thread synchronization (Score:3, Interesting)
What I think the author is trying to say is that "Premature optimization is the root of all evil in programming". Most of the stuff enumerated in the article usually has a minor impact on performance and no programmer should worry about them during coding.
However, when all the coding is over, the system will have to meet some performance criteria. If it crawls like a quadraplegic snail, a programmer will have to get its hands dirty and tweak his code to remove the bottlenecks.
It is very possible that one of those bottlenecks will be rooted in these so-called "urban legends". Gross over-allocation of immutable objects and synchronized methods may impact performance.
It happened to me a while ago. I was working on a system that was designed to use lots of threads and message passing. We had completed the development and were ready to move on to testing. The system worked pretty well on the developers' workstations (1 CPU) but when we deployed it on our much more powerful servers, the throughput went down. At first, we thought that it was a thread contention problem but after some testing, we realized that the cost of obtaining a lock on multiprocessor systems is orders of magnitude higher than on uniprocessor systems.
This is because on uniprocessor machines, thread synchronization simply amounts to doing an atomic if/set. However, on multiprocessor machines, complex mechanisms have to be used so that the lock becomes effective for both processors. It involves a lot more overhead because the required extra-cpu operations cost a lot of cycles.
It is a trade-off (Score:3, Interesting)
Of course, some people interpret the statement to be a comparison to C or C++. Now, Java has a lot of behaviors that are slower than C/C++.
For example consider array access. Java implicitlu checks the bounds of an array whereas in C/C++, that is leftas an exercise for the programmer. Unfirtunately, most pogrammers are lazy and don't exercise that. Hence with C/C++ you have buffer overruns where nasty clients can execute arbitrary code. In Java,you'd have an ArrayIndexOutOfBoundsException which would prevent the malicious data form being pushed into memory. This, it was a trade-off between security and speed.
Garbage collection is another one of these. Ever seen a C/C++ program with memory leaks (why, I even remember the X11 libraries leaking)? With Garbage collection, your memory consumption is slower and your memory freeing slower (since Java has to determine using an algorithm what isn't used anymore whereas in C/C++ its coded into the logic). Java also seems slower becaus ethat GC overhead is generally experiences as "pauses" whereas n C/C++ the object deletion occurs through the execution of the program. But this was a trade-off. A trade-off between making developers lives easier and the programs more stable versus the speed and risk of developer-coded memory deallocation.
Java also has immutable Strings With a mutable String class, I know I could eliminate a lot of Object creation. But the String class was made immutable so everything could be final, and thus optimized better for. This was a trade-off between the speed of Strings themselves and the speed of creating a new String everytime you need to concatenate.
There are many more cases, but I think you get the point. Java does things ways that are slower. But many of these are trad-offs -- trade-offs to make the programs more secure, development faster and syntax/API simpler. Then they go and address the speed in other ways by improving the VM (HotSpot, incremental/concurrent GC, etc.)
In my opinion, I would've accepted a 100% Java version of Microsoft Outlook, even if it was slower, if I didn't have to worry about the nex buffer overrun exploit hijacking my computer.
Tuning garbage collection (Score:4, Informative)
http://java.sun.com/docs/hotspot/gc/ [sun.com]
Normally you would have an idea how the memory footprint of your J2EE application would be. Do you have long lived objects, or short lived objects? Do you create a lot of new objects in your code? Are there big static tree-structures? Tuning with this in mind could be what makes your application run at all or not at all when the load comes.
In particular is it a good idea to configure the garbage collector so long lived objects are seldom attempted garbage collected, while new temporary objects are cleaned away so that the allocated memory area are fast freed. Your goal should be that the system should never really need to do full GC.
One example of this is long startup time due to several full GC in the process. Solution - configure your system to start with sufficient memory from the start. Your system shouldn't be needing to hit full GC without managing to free enough memory.
If you have a J2EE application with EJBs and stuff - make sure that the OLD region is big enough to keep all the pooled objects, and that the number of young survivor spaces are many enough that you don't move "use and throw" objects into the old region.
Thinking in these lines you might be able to make your server applications only perform full GC when the system "feels that it needs to", and not when it must. (For instance at the timed intervals due to GC in relation with RMI).
A sideeffect of optimizing like this is that one needent worry about creating new objects - allocating a new object only takes a couple of cycles of memory management (moves the free pointer), and if you configure the GC to wipe such objects using the incremental GC (fast!) then memory management shouldn't become a bottleneck. (Not counting in the actual initialization process - if it is costly, reusing objects would probably be a good idea...)
KEB
final methods (Score:3, Informative)
An online Starcraft RPG? Only at [netnexus.com]
In Soviet Russia, all your us are belong to base!
Karma: redundant
Here are the results I found, the code is below:
First test, method1 is not final
Running method1() TIME: 4577
Running method2() TIME: 4596
Running method2() TIME: 4637
Running method1() TIME: 4547
Running method1() TIME: 4547
Running method2() TIME: 4566
public static void method1() AVERAGE: 4557
public static final void method2() AVERAGE: 4599.66
Second test, method1 is now final
Running method1() TIME: 4557
Running method2() TIME: 4576
Running method2() TIME: 4537
Running method1() TIME: 4597
Running method1() TIME: 4636
Running method2() TIME: 4557
public static final void method1() AVERAGE: 4596.66
public static void method1() AVERAGE: 4556.66
Here is the code I used. Its ugly, but I did it the way I did to best mitigate the effects of the JVM optimizing the code:
Re:Java for Applications.... (Score:2, Insightful)
SWT [eclipse.org] rules!
Java vs. RAM (Score:5, Informative)
Oh, good, another one to shoot down. While I don't have any numbers at all, I know that Apple 'fixed' this problem to an extent by making parts of java shared, just like any shlibs. This alleviates the 14 apps, 14 bags of shit problem to some extent.
Apple then returned the changes to SUN, who rolled them into 1.4.x.
I wish I had numbers. Sorry.
Re:Java vs. RAM (Score:3, Funny)
Re:Java vs. RAM (Score:3, Informative)
Apple has indeed implemented shared memory for system class generation [apple.com] (since 1.3 in fact), but it has yet to be backported to a Solaris/Wintel/Linux officia
Re:Java vs. RAM (Score:4, Informative)
From http://www.apple.com/java/ [apple.com]
Apple developed an innovative new technology that allows Java code to be shared across multiple applications. This reduces the amount of memory that Java applications normally use. And it fits right into Sun?s Hot Spot VM, allowing Mac OS X to remain compatible with standard Java. In addition, Apple has given this implementation to Sun so the company can deploy it on other platforms. Just one example of how Apple supports standards and shares ideas to benefit all.
You're right in that I can't find any evidence that SUN has rolled this. My hope would still be that this is will be Java Myth of the future. For now it just sucks not to be an Apple user.
I don't know about Anm's experience on his PB...
Re:Java for Applications.... (Score:5, Interesting)
The first mistake, of course, is that people think that (a == b) == a.equals(b) which is, of course, only true if a and b are constant strings or one have invoked intern() on them.
The second is to not realize that string concatenation with the "+" operator is a special case and only syntactic sugar for StringBuffer operations. Thus, someone not familiar with Java may accidentally generate huge amount of StringBuffer objects in loops.
However, both these things are very fundamental Java knowledge and among the first thing you learn when studying Java. It's obvious that you don't start coding serious Java without knowing how try..catch..finally works, and equally obvious that you should the know about the deals with the String class.
Re:Java for Applications.... (Score:5, Interesting)
But I can tell you, the that almost every Administration application that runs java, sucks out my soul. Trying to run java applications over X at long distances makes me want to commit suicide. (Lucky theres VNC, so its almost usable...) (I think its a Shared memory problem with the way it works with X windows.)
Then there is the damn JVM's that each app needs, and how i can have multiple versions loaded, so each application works correctly. Java 1.1/1.2/1.3/1.4 and now 1.5 should take even more disk space. Doesnt seem anything is upgradable in java.
And lets not forget, about how Java likes to interact with all custom window manager replacements on windows. For some reason the screen flickers every time you run a java app. (Havnt seen any answers, but it messes with lightstep, blackbox, geoshell, and even stardock applications.)
Humm, and cut/paste sucks, yes you can use key combos, but sometimes in windows, its nice to select all, and copy. (Minor bitch, but still annoying when you have switch ways of doing things...)
If you cant have command line, and you must have a GUI, for gods sake use a HTML. I now make it a point to go with vendors without Java interfaces, they clearly dont use their own products on a day to day basis.
BTW, i said java Interfaces, not Java Beans, etc. We have java running on solaris, works fine, other than the memory leaks. Its the Admin applications that use Java that are crap.
Enough about the things Java can never fix. (Score:5, Insightful)
JNI is the NATIVE INTERFACE. For those that don't already know, that's the interface to the underlying operating system. If the OS misbehaves, hiccups, or is inconsistent, when did it become JAVA's responsibility to clean up? When somebody decided that JAVA was getting a black eye because OS call foo(bar) was crashing the application, or better yet didn't behave exactly like foo(bar) on every OS that provides the JVM.
Don't like AWT? Well mabye that's because it's built on top of JNI. Enough said.
Don't like Swing? Well you'd better like AWT. If you don't want the OS to do your GUI work and you don't want the JVM to do your GUI work, mabye you should just get a dry erase marker. You can draw the boxes you need on the screen provided you use a tissue between display updates.
String requres no more attention than any other bit of JAVA code. If you create dozens of objects for the sole purpose of garbage collection, you either just learned JAVA, you're unaware of what you're doing, or you don't care.
And about garbage collection. JAVA's garbage collection may not be your cup of tea, but neither are the memory leaks that are still being cleaned up in systems that lack automatic garbage collection.
So pick your posion. If JAVA isn't perfect, that dosen't make it horrible. JAVA is a good language by most standards, but be honest by stating that it isn't good by your standards.
My biggest reason for liking JAVA is that it forces people to stop writing bad C code. Which is exactly what it was designed to do.
Re:Enough about the things Java can never fix. (Score:2, Insightful)
I assume you know (Score:3, Interesting)
For example, should I have a program that has 8 threads and the whole thing uses 28 mb of memory.
A process listing shows 8 entries each using 28 mb of memory, when in reality only 28 mb and not 224 mb (8 * 28) of memory is being used.
Before you blame this one on JAVA too, you might want to know that it's a bug in the concept of process memory reporting (ie. the OS) not JAVA. The OS lists 8 scheduleable pr
Re:Where are the Java desktop applications? (Score:3, Interesting)
OpenOffice at the very least uses Java within it.
Hotjava is a functional web browser.
Java just isn't popular on the desktop, because you never know what crazy JVM version someone's going to have on their system. But there's definately a place for it.
Re:Where are the Java desktop applications? (Score:4, Interesting)