Java Performance Urban Legends
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."
sounds like the optomizing needs a little, well, optomizing
"Sanity is not statistical", George Orwell, "1984"
has poor start up time, and requires an absolutely massive amount of memory. That, and garbage collection makes almost-real time ("soft" real time I believe is the technical term) UIs more difficult than they should be.
Also, Swing is a bloated pig.
JNI (native interface) can swap huge numbers of arrays back and forth if you don't test for it and have a fall-back mode.
These are huge pitfalls, even on our multi-GHZ beastly desktops. But they are the only pitfalls.
String requires careful attention.
That's all she wrote folks, I didn't even read the article (should probably post anonymously!) but I've spilled the beans. Nothing else to say.
I wonder to what extent this exists in other languages? For example, there is an oft-cited tip that says using persistent database applications with LAMP applications increases performance. I've found in actual practice that this depends on a lot of factors such as server load, amount of available memory, etc.
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.
My journal has hot
There was this one guy who worked for Sun Micro and was disappointed at how slowly Java ran on his Sparcstation, so he attached one of those JATO rocket engines...
k.
"In spite of everything, I still believe that people are really good at heart." - Anne Frank
Fluff. My post is superior.
Post the source code here and all "urban legends" about it will soon dissappear.
Ok, so none of the things we thought were slow are really slow.
Then why the hell is it so slow?
Urban legends are kind of like mind viruses
Are you new here? Usually people call this kind of thing a meme.
The best tip in the article, which really applies to any language (even to choice of languages), is IMHO
"Save optimizations for situations where performance improvements are actually needed, and employ optimizations that will make a measurable difference."
I wouldn't mind if it was pure Java, but that's far from the case. Pure Java GUIs can be fast (but memory intensive), it's a shame that SWT is currently the only "alternative" to Swing because it's such a horrid choice to make - Slow but pure or Difficult to use, platform-dependent and fast.
Interesting. As a guy who's been a die-hard PostgreSQL for a number of years, and who recently accepted a job doing hardcore MySQL administration, I was dreading it, because everyone knows MySQL has bad transaction management, horrible administration nightmares, and is only good for developers.
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 is on a wiki, so feel free to register and add your own experience. Please be ready to back up your opinions with facts.
fifth sigma, inc.
sounds good to me.
Save optimizations for situations where performance improvements are actually needed, and employ optimizations that will make a measurable difference."
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
I'm not Seth.
Interesting. A text that say that some things in java are not as slow as people belive, and yet it fail to deliver any prove anything. For ekample it say: synchronized methods are not slow, and yet it include no benchmark/test to backup that claim.
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 exists.
I really wish that the slashdot editors would read the stories and dismiss the one widtout any information.
(Yes I know, the slashcode is free, so I could just make my own news-site but life is to short, and the studie take to much time.
One thing to remember is that Java is a 'marketed' language. Hence, be aware of inevitable corporate propaganda. That's not to say that Java is bad, but it is heavily pushed.
Here's a bit of an antidote: Why Java will always be slower than C++
Yes it sucks to run java but no one uses java applets anymore. The killer app is java server side ecommerce. It's beating Microsoft so we should like it!
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:
- Memory allocations
- Function calls
Of course, if you can do this in C/C++, it will also improve performance, but it is not as critical to be so careful in these lower level languages.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.
It must be all these Java "programmers" that University CS departments world wide keep churning out that couldn't write a well performing program if their life depended on it?
*looks at Limewire*
*looks at administration applets written by Sun which don't work over X11*
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% speed increase.
news article . BEA is.
has poor start up time, and requires an absolutely massive amount of memory. That, and garbage collection makes almost-real time ("soft" real time I believe is the technical term) UIs more difficult than they should be.
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.
Running Freenet and only freenet
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
Live today, because you never know what tomorrow brings
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.
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.
Back in mid to late 1997, Java performance was horrible, particularly on Linux. I remember being very happy with the performance of my development box (dual PPro 200, 200MB of RAM) at the time, except when I was running Java apps. It also used tons of RAM just to start an application, and then it leaked...
I'm sure that all of this has gotten better in the 5 years since then. It doesn't really matter to me though... After 6 months of trying to be happy with Java, I switched to Python. It's working fantasticly for me.
Sean
Finding where your software spends most of its time can be hard. Having a tool measure resource/time consumption of the regiouns of source code is critical in finding bottlenecks and improving performance.
"Java Performance Urban Legends" should read "Java Performance is an Urban Legend".
Tarsnap: Online backups for the truly paranoid
Why ? Because it depends so much on the performance optimizations the JVM employs.
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>
The Raven
I'm all for calling a spade a spade, but you can't have your cake and eat it too.
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.
that the operating system duplicates the amount of memory reported for each thread in a JAVA program?
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 programs (the java threads) looking up the amount of memory each has access to (28 mb) without ever hinting that they are all using the same 28 mb.
Well JAVA has features that are mostly missing in the languages that it is compared to.
So any time someone compares your programming environment to say, a car, you are experiencing what most people do to JAVA.
What you fail to understand is the real world doesn't matter. There is a special case in which that might not be true and someone might code the JVM that executes the special case, so the horrors you speak of are superfluous!
-pyrrho
One of the links in the sponsored content box on the left is "buy viagara online".
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.
Yeah good point.
:) Of course you gotta be careful how you measure whether or not something degrades or improves performance. You've gotta find some way to get a measure of how only the specific change you're making affects performance, which can be tricky - ie: you end up measuring other stuff which overshadows your change, or don't do enough iterations, so the overhead involved overshadows you performance gains, etc (similar to how some sort algorithms kick ass, but only for sorting large lists,etc ). So it can be tricky deciding what's better just by throwing together a quick test.
Speaking of other languages, one thing I've noticed is folk applying concepts from one programming languages (or environment, system, etc) to another, maybe starting these sorts of "myths." For example applying concepts from a low level language A to a much higher level language B without much knowledge of what the compiler/interpreter/etc for B is really doing, and how it differs from A. Or even simple stuff like making incorrect assumptions about how the compiler does something can cause problems.
Anyway I guess the point is, as you say, try it first!
I guess my suggestion is don't just believe it when you're told that XYZ is good or bad programming practice. Instead, make sure you understand why doing XYZ, is good or bad.
Posted by CmdrTaco on Sunday February 09, @09:46AM
cowmix writes "It turns out that Sun does not eat its own dog food. Specifically, this internal memo from Sun strongly suggests that Java should not be used for Sun's internal projects. More interesting still, they go on to state which other languages fullfil Java's goals better than Java does itself. Finally, the memo states Sun's own Solaris is the cause of many of Java's woes. Yikes."
My favorite pieces to quote:
Less is more !
I wonder to what extent this exists in other languages?
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.
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.
A lot of them are things that actually used to be good advice, but for some reason or another (changes in hardware, compilers, etc.) aren't anymore. For example, it used to be a good idea in C to iterate through arrays by incrementing a pointer and dereferencing it instead of incrementing an index and then using array subscripting -- that way you had one increment per iteration, instead of one increment plus one offset calculation (basically you saved the addition that takes place during the array subscripting). However, on many modern C and C++ compilers in many situations, array subscripting will actually be faster than the pointer-incrementing method, because it's easier for the compiler to perform certain optimizations with. [Reference: Michael J. Scott, Programming Language Pragmatics (Morgan Kaufmann, 2000).]
There's quite a bit of other stuff like this out there as well.
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
JAVA designed the JVM to be a "raw" machine. That means that there is very little for it to do when it starts up. That's why the JVM starts so quickly... except:
The last function of the JVM is to load the java library. A beastly collection of objects which comprise the JAVA language. Yes, nearly everything you use in JAVA (including the language) is modular. Hence, the machine takes more time to load your program since it's next in line (right after the JAVA language).
If you dump the stock JVM and get one with the language libraries built in, you get much faster start times (at the expense of flexibility)
for example:
public String indent(int indent)
{
String output = "";
for (int x= 0; x indent; x++)
{
output += "\t";
}
return output;
}
If you use this function you are waisting cpu power like crazy because strings are immutable. This has nothing to do with the jvm, but is inherent in immutable strings, no matter what language they are in. Here's the reason... output starts as an empty string then the first "\t" is added to it. What the compiler MUST do is create a 3rd string of the length of both output and the "\t" string. Then it copies all of output in to the new string then the "\t". On the next loop output = "\t" and we add another "\t". To do this we make a third string again and start copying. BUT we already copied everything in output to a new string once already, so we're copying it for a second time. This is where we waste cpu cycles, and this is why not using immutable strings properly can cause problems. By the end of the function, the first "\t" is copied indent number of times, to indent number of temporary objects. If we change the function to..
public String indent(int indent)
{
StringBuffer output = new StringBuffer();
for (int x= 0; x indent; x++)
{
output.append("\t");
}
return output.toString();
}
No temp strings are created. No "\t"'s are copied. Thus we don't waste cpu cycles.
I do agree this is a problem, but in many cases the Java behavior is actually better; a lot of C/C++ slowdown is from realtime memory management, and could be sped up by saving up stuff to do later (this can be done manually with C++ allocators, but is often a pain in the ass).
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
They're actually quite open about it. I took a websphere class with'em, and the consultant made many funny remarks about microsoft, c#, and even sun. (their eclipse does that do the sun???)
"If anything can go wrong, it will." - Murphy
I keep getting a time-out whenever I try to access it.
Where are the Java spreadsheets, browsers and word processors? They don't exist. Why is that? This is not a flame - if the Java language is as good as C++ then why are all critical feature-filled applications that you use every day written in C or C++?
Don't moderate - post an example of a useful java desktop application.
The underlying point of the article was not that X is fast or Y is slow, but that you should be skeptical of blanket statements like "X is fast" or "Y is slow", because (a) these statements are highly time-dependent (JVMs get better), (b) they are highly JVM-dependent for the reasons you state, and (c) they are also dependent on other factors.
BTW, your point about final methods makes a bad assumption on the limits of optimization. A smart optimizer would figure out that no other loaded class overrides a given method, and would optimize accordingly, whether or not you've hinted so by declaring it final (and if a class was loaded later that overrode that method, the JIT would invalidate code that depended on this assumption.) I'm pretty sure that TowerJ did this.
I guess my suggestion is don't just believe it when you're told that XYZ is good or bad programming practice. Instead, make sure you understand why doing XYZ, is good or bad.
Of course that's half the problem. The article mentions two programming practices, and each of them have a grain of truth. The sync/unsync issue used to be true, and the other one, the use of the final delcaration, seems to make sense but it doesn't actually work that way. Hence the reason I suggest that people actually try something before accepting even a seemingly plausible explanation for what amounts to voodoo programming practice.
My journal has hot
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?
There are some performance issues with Java. That's a fact. But, on the other hand, Java is faster than most people think it is: take a look at http://www.jrman.org for an example of a Renderman renderer written in Java which is much faster than Aqsis (a renderman renderer written in C++)
SWT is platform dependent in the sense that you have to include a different package with your SWT app to make it work with each supported platform. This is in a way true with Swing, but since Swing is SUN-sanctioned, the customizations for a particular platform are part of the JVM for that platform so the distribution of a Swing app is more transparent.
i think this is prevealent in other laguales if not all other aspects of computing.
the fact is most people take one method to be faster than another without ondertanding the reason behind it. how often do people look at the number of sys calls or O() of a funstion they use. Simply put if you dont have some sort of theoritical backing to you claim that one method id faster than another, it cant bebelieved.
The war with islam is a war on the beast
The war on terror is a war for peace
Umm... MoneyDance?
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.
Somebody mod this guy up, those are the best lines I've seen all night.
I'm a writer, a poet, a genius, I know it. I don't buy software, I grow it.
What kind of Loonix hippie are you?
Tell Transgaming to fuck themselfs and go and pirate a copy of 98 to play your games.
How does anyone really know for sure that some urban legend really did not happen? Take the dog drying case. It's certainly plausible, as urban legends do stick around when that is the case. But a microwave oven is actually a lousy way to dry a dog (or anything for that matter). This legend, though, might have been derived from a case in the late 1960's when a woman in Ohio did (try to) dry (and did kill) her dog in a conventional oven.
If you really want to dry your dog safely, you need to get one of these.
now we need to go OSS in diesel cars
In a real project, using JDK 1.3 on various platforms, we had performance issues. So, we measured speed in various ways, and found three main problems.
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.
I can just as easily pull some facts out of my ass. Jees, you java guys are thin skinned. I work with Java everyday and I agree with the original poster - it's fucking slow as hell to start. Grow up. After driving a supposedly turbo-charged 4 cylinder car for a couple of years I too began to think it was pretty fast - then I had the pleasure of driving an old V8 - no comparison. Be objective. Everything has its strengths and weaknesses. Java's libraries are its strength and its startup time and memory footprint is definitely a weakness.
First postt!!!!!!1 -Support DeCSS, Nmap, crypto, and the RIAA
Research into bird songs has resulted in this project: http://birds.cornell.edu/brp/Raven/Raven.html.
I tried it out: it is the dancing elephant; you tend not to focus on the quality of its dancing but on the fact that it dances at all. An oh yes, while the Raven UI is not exactly sluggish once it gets going, it takes ever so long to load on starup.
Just from reading the post description it left me wondering which urban legend they were going to disprove; that java isn't slow or that it really is after all.
.NET will have this problem too as will any language with a builtin String type and garbage collection.
Seriously, saying "Java is slow" is not a very sophisticated viewpoint. Using String objects a lot is slow. The Swing UI is slow. This knocks out a lot of potential uses. No improvements in JVM technology are going to fix that I'm afraid. And
If you write Java like you write C it's not slow. If you're not doing constant string processing it's not slow. It depends.
Java is not always slower. Java's interpreted nature is generally seen as a weakness, but it has advantages too. For example, the JIT has profiling data immediately at hand when doing optimization, whereas compiled languages won't. Even in cases where compiled languages do use profile feedback, it may not be representative of the current program usage.
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.
Interesting.
Intel's optimizing compiler helps it compete with other CPU manufacturers.
Microsoft once sold a slow Pascal compiler. This doesn't seem to fit, but most of Microsoft's operating system sales are to computer manufacturers. This puts pressure on Microsoft to make its software as slow as customers will accept. Later Pascal compilers, by other vendors, were more than 10 times faster on the same machine.
There is heavy competition in C++ compilers, so Microsoft's version is fast.
What about VB? Is is fast? For most of its lifetime, I've heard that it is not. No competition.
Probably the DEC hardware sales people were a dominant force in the company. I can think of a particular situation in which a company that was pushed to add a new VAX, when faster compiler output would have been better, and half the cost.
Performance analysis from this project to develop a high performance platform for internet services(http://www.eecs.harvard.edu/~mdw/proj/sed a/index.html) shows that Java can be better than c/c++.
But in general, if your application involves a fair amount of I/O, the programming language isn't likely to affect performance all that much.
What most people "know" about Smalltalk (slow, has reference counting garbage collection, requires too much memory) was arguably true 20 years ago, when it was truly pushing the envelope.
I write in C and asm so it is slow. Games programing when java can do quake3 without overloading the system I will be impressed.
Basicly I want to see is java to binary ie Java classed to precomplied native binary(programs using all the time speed speed speed). Ie less runtime compling. Java and perl have about the same performace. C++ has never been a great bench mark as it is different on UNIX related and Microsoft.
I will say it is slow until is show me that it can move with the speed I want.
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.
While you can't state that a given idiom will improve performance of a program, you also can't state that a given idom will have no effect, either. In particular, the author claims that making methods final has no effect, but fails to show it. The whole article was marked by the same lack of solid evidence the author was decrying. As far as I'm concerned, these Java idioms are still open to question, and the information content was minimal.
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).
The standard java NIO APIs support non-blocking IO (which is what select() is).
Wrong answer, but thanks for playing.
True interpreted languages are slow. When you write a script for bash, it's read in line-by-line and parsed each time you run the script. (But it's also slow because you typically are creating lots of different processes, which is why being interpreted is the last performance problem you should worry about in shell scripting.)
Java is not interpreted. Java is compiled. Whether the format to which it is compiled is native for your processor or not is an entirely different question. Java (similar to Perl under mod_perl or other schemes) emulates an idealized Java processor, but it does not interpret it. This is much faster that interpreting a language.
Those of you who used the first PowerPC-based Macs have experienced the difference. Almost all the applications you ran were compiled for m68k, but Apple had a software m68k emulator that ran them several orders of magnitude faster than if your 601 had been interpreting the C (or often Pascal) sources.
The reasons languages like BASIC or Perl (regardless of whether they are interpreted or compiled/emulated) tend to be slower than languages like C and Java are:
Gates' Law: Every 18 months, the speed of software halves.
Again, if you really need to have everything in memory at the same time, get more memory. Or just learn to trust your OS's memory manager to page for you.
Gates' Law: Every 18 months, the speed of software halves.
ThinkFree Office is a set of office applications that uses Java. I nevered played with it, but apparently it's not bad. Also, there are tons of IDEs out there that uses Java and works quite well. My personal favorite is IntelliJ. I use it on OS X, and granted, it's not as fast as Carbon/Cocoa apps, but its performance is quite decent on my 667MHz PowerBook, and I can imagine with a newer machine it would be even more acceptable.
Read the article. It thoroughly explains why you're wrong.
That sounds more like an issue with FreeNet than anything else. If anything, you sound like you'd be more interested in the memory footprint of a "Hello, World".
It ain't 70MB.
I used to be the best damn VB programmer there was until around version 6.0. Well, maybe not the best, but I sure did some cool stuff with VB. I got started years ago with GWBASIC too. IBM made one of the first PC compilers for BASIC called "BASIC Compilers 1.0 and 2.0" This was the pre-mouse era, 1985-87'ish days. For lack of a good editor, I used the GWBASIC interface. When we finally compiled with the 1.0 compiler, the code ran a good bit faster. Then, we got the 2.0 compiler. Oh god how slowly our code ran with 2.0. I don't know what happened with 2.0 but it just didn't cut it. We ended up selling our program compiled with the 1.0 compiler.
Later, around 1988, we got our hands on the first Microsoft QuickBasic compilers. The compiled code then ran like lightning! We found that the QuickBASIC's used the new P-code interpreter. I used QuickBASIC quite a bit. Later, in the early 90's, I changed to VB around version 2.0. VB was quite nimble for program size and execution speed. But when we got version 4.0, it would compile to native code. This was the best performance I ever got out of VB before I realized...hey, the language just isn't giving me what I wanted...eg...smaller size, and faster speed.
Actually, I had been programming in C since around 1989. And, the more I used C, the more skilled I got at writing C code. The break point came with VB 6.0. I just couldn't justify using VB anymore as it wasn't a good environment for writing command line system administration programs. I was entering into systems administration/programming as my main job, so my code needed to run fast, lean, and mean.
When the Java phenomenon hit, I saw clearly from my VB experience that this just wasn't going to be a pretty scene. On the one hand, you had plenty of newbies who really didn't know anything about programming spouting the Java mantra. And, with the Internet, it seemed the entire world was going Java. The two bubbles of Java and the Internet seemed to go hand and hand.
The state of Java now is pure and simply...just bloat. For example, just download and run Morpheus. The thing is written in Java, and for just a simple application, uses 54 Meg. What the heck, 54 Meg!!!??? And, this C# stuff that Microsoft is producing just isn't any better. A simple C# hello world program uses 11 Meg!
I just can't use applications that take seconds to minutes to load up, then use up all my memory, then run slow as Christmas. I'm a systems programmer, I write applications that load, do what they need to do as fast as possible, then completely unload and get out of the way. My apps have to run background'ed so they don't interfere with the users. I don't want my memory used for program space, it's supposed to be used for data space!
You might say that memory, disk, and GHz are cheap now. Well my response is...so are your coding skillz! The one thing I've realized over the years is that the more time you spend programming in these high level languages, the more real experience you lose where you could be coding smaller and more efficiently nearer to the core. I'm trying to say that maybe I wasted a good bit of time in VB when I shouldn't have. The same goes for the Java guys. We had a great programming language called C, and C++ that got pushed to the back-burner because of some people who decided that garbage collection and VM's were a "good thing". Well, maybe they are, but at the expense of expertise in programming? I mean come on, if you can't handle pointers, can you really call yourself a programmer?
I'm so tired of programming environments that keep people from shooting themselves in the foot, or coddle beginning coders. Programming is a skill and an art. It is a good bit like architectural design. Java and VB just turn things into manufactured housing. Do you "want" to live in a double-wide home, or one that was designed to be functional, strong, and beautiful?
I suppose I'm being too hard on everyone here. Heck, I still use VB
I can only imagine it's always sucked not to be an apple user. the apple ][ was awesome.
I used to have a better sig than this, but I got tired of it
Hmmm... while I understand what the author is trying to say, I believe his article is misguiding. The problems he mentions are not urban legends and could conceivably be at the root of a performance bottleneck.
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.
That memmo was written in 1999
ReadThe ReflectionEngine, a cyberpunk style n
I don't put much stock in performance tips that are offered without explanation. And in deciding whether to use a tip, I weigh not only the performance trade-offs (near call vs. far call) but also the programming trade-offs (single source file vs. modular code). End-users want reliable functionality, and efficient programming practices often make more difference than code tweaks.
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 scorers" in the profile. By changing ~200 lines (spread over a variety of classes and functions) I managed to bring the speed up to ~55,000 values per second. So that's 0.1% of the lines, and an 18 times increase in performance. That's not a bad result for one afternoon of careful coding.
Were those 200 lines so badly written in the first place? Hell, no. They were fine. But there was a potential for improvement here, and making that improvement had a discernible effect throughout the system. I could spend the rest of my life improving the rest in the same manner, but I doubt I could get another factor two out of them.
It goes without saying that without the profiler I could never have done this.
For the record, I found that there were repeated calls to strlen() in a tight inner loop. The most important thing I did was eliminating that call. Smarter buffer management did the rest. The biggest remaining bottleneck is actually in sprintf (%f) - the conversion from float to string is comparatively slow. Just generating all the values without doing that conversion gets me a speed of around 180,000 values per second.
(*) And if it hasn't, do yourself a favor and get a real development environment. Please.
IBM's current buisness strategy depends on Java. They're about the last people to 'set anything straight' about Java. They'll happily tell you that Java is perfect for your every need and that it will give you a blowjob too.
Could you not imply that the most biased source is unbiased? Jesus Christ! Next thing you know you'll have unbiases appraisals of Linux by Linus and Stephen King's new review of his own new book.
The question of Java performancd can be quite subjective. For example, I run jEdit, a 100% Java text editor. It's fast. Unforunately, its not as fast as native Win32 editors like UltraEdit or TextPad. However, my mind and body can only work so fast. Both jEdit and the other text editors are faster than I need them to be for my day-to-day operations. So, by that measure, Java is fast.
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.
This is exactly the kind of advice where you end up trying to optimize a bubble sort. No wonder you posted this as an AC. :)
Goetz is in denial and just waves away problems using straw men without providing a truly balanced view of cases where these things cause problems. It depends on the VM, if things are done in a tight loop, and so on.
Suffice it to say I did not like this article. As always, you need to measure application performance for yourself to find true bottlenecks.
-Kevin
I disagree with the author's advice discouraging the use of final classes and methods. Both from a design and a performance method, I think final classes and methods are underutilized by programmers. For an in-depth essay on why, see here.
This is a FILE LEVEL backup - you have to flush the daemon's write cache back to disk.
While MySQL allows you to simply block updates temporarily, PostgreSQL says you must SHUT THE DATABASE DOWN COMPLETELY (http://www.postgresql.org/docs/view.php?version=
Opportunity knocks. Karma hunts you down.
Many Java programmers still don't understand synchronization and Java threading. Synchronized code is slower than unsynchronized; this is normal and there's no way around it. The problem is many programmers appear to take a "just in case" approach to synchronization. For most java developers, synchronization shouldn't be much of an issue (rarely if ever should you need to mark code synchronized). Synchronized code, used correctly, doesn't have an obvious performance penalty because generally it only needs to be synchronized because of a shared resource that should be much slower than the JRE. Working with Socket springs to mind. A thread-safe container is a much more efficient approach in other cases.
The "final is faster" stuff is totally irrelevant, even if it is true for some cases, particularly static final methods. However, final is not Java's answer to c++ inline. Final is there just to say "do not override this." If the reason it's there is for "performance," it shouldn't be there.
The immutable object thing is equally irrelevant. Strings are a particularly pleasant illustration, taking the argument about them to its logical conclusion leaves you with an array of char. If that's what you want to work with, what you probably want is a C compiler. You can look under the hood at StringBuffer and String and try to dope out what the compiler and runtime are doing. The better approach is to think about what you're doing, and make sure you're thinking in Java. Often if strings are actually the bottleneck it's because the coder wants their perl or c approach to a problem to work, not because garbage collection is more efficient one way or the other.
In many ways, I wish primitives weren't exposed in the language. It would be a subtle hint to those who still think with pointers, arrays and free() in the back of their head "this isn't C" and reduce the stupid performance tricks people try. I also wish prior to 1.4 javac had issued a "this isn't perl" warning if you used more than a couple StringBuffers and StringTokenizers per class. Alas, with java.util.regex those who approach every problem with "I need a regular expression that will..." can wrap their bad habits in Java code, and 1.5 seems to be devolving to c++ with crappy pseudo-templates and precompiler-ish directives.
Reference counting is most certainly sub-optimal for a great many situations.
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
Use a profiler. It will tell you exactly where your bottlenecks are.
When I first started using the STL my instincts told me "this much functionality must come at a heavy price" but when I profiled my code, the STL map was way way way down there on CPU usage.
The old myth that floating point operations are slower than integer is wrong too. We tested that one 5 years ago and a floating point operation of the same values often beat the integer operation.
Exceptions are often decried for being slow, but, if you profile code you find that function calls 3 levels deep or more are SLOWER if you check error returns at each level that if you have a catch clause. This test was done with the Visual C++ compiler version 6.0
This was all done on Pentium class chip.
Strange.
Java has a profiler built into the JVM, and if you want a prettier interface with real-time analysis options (Like watching object counts as they're created and destroyed, etc) then you can buy one of any number of commercial profilers.
It's possible that on some micro-benchmarks like the one you mention, Java with JIT might outperform some other languages on some edge cases. But for real systems, Java is slower. I've more than once had to port Java systems to other languages for no other reason than speed - and the speed improvements have been dramatic. One big issue seems to be that method dispatch in Java can be relatively slow. And since everything's a method...
There was about a decade when I wouldn't touch a mac. And I have no regrets at all about that. From 86-98, or so. In 88 the NeXT came out, and MacOS was stuck in single user, no protected memory, no multitasking.
What a piece of crap.
I had absolutely no respect for the platform. I saw the NeXT glossies and was totally in love. I mean... Unix, Display Postscript, OOP; it was the only platform to own.
But I'm biased, as you can see from my resume' at my website.
Umm, Java applications don't run in web browsers...
I am TheRaven on Soylent News
You said..."Not all programs have the same requirements. In most cases developer time is much more valuable than CPU time."
This is a funny thing to say. I think end-user time (and resources) is much more valuable than developer time! That is why they are paying for your progam in the first place.
You said..."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."
You should be surprised. Sure, techniques are independent of language. I may have been wrong to use the word skillz. More precisely, part of being skilled at something is experience. Experience in one language does not directly translate to another very easily. Verbal languages that people speak around the world is an example. The syntax and constructs might carry over easily, but learning what all those words mean (or do, as in the case of programming languages) can be hard.
I can't justify telling everyone to use C all the time. Of course, every problem has a specific solution that works best. You are correct, there is a trade-off. I'm just saying that, over time, you may regret not knowing something well that is, in fact, more efficient and effective for writing compace and fast code. I sort of regret all the programming time I threw away with VB. But, I still use it when push comes to shove, and I guess I should be happy I know a good bit about the language. Being versatile is good, but being a jack of all trades, master of none, sucks!
+4 cent.
Q
Java just isn't popular on the desktop, because you never know what crazy JVM version someone's going to have on their system.
Wrong. Java applications can be distributed with their own private JVMs. Check out InstallAnywhere for more details.
Q
Joel Spolsky was theorizing about Sun in what he calls Strategy Letter V. (See the bottom for the paragraphs about Sun.) He wondered why Sun wants Java, and he was not able to guess.
Here is a theory: Sun wants its own software to be secure and fast. However, there is a conflict of interest. Sun makes more money if its customer's software is easily de-compiled. If Sun sales people find one customer doing particularly well, it is easy for Sun's other customers to de-compile the original customer's Java code and re-write it to work for their own purposes. This would benefit Sun because the salesmen could more readily sell the hardware that runs the Java program. Slow and easily decompiled makes more money for Sun.
Did I make enough jokes in my parent comment about Java being slow? They should rename Java and call it InsultMe. Most of the time when I see a Java program, it is so slow and the GUI is so quirky that I feel insulted that someone expects me to think it is acceptable.
Most programmers are ignorant of how to create simple performance tests in order to verify urban legends for themselves. This includes a lot of open-sourcers and IRC lurkers as well.
Professional (not most) programmers and project managers can't afford such ignorance. We test things, and build our opinions on fact rather than heresay. New programmers should consider the difference between heresay and experiment.
Java performance urban legends are low-hanging fruit -- easily debunked. Anyone who propagates these sorts of rumors clearly doesn't have the experience to construct valid tests. But testers who have bothered to check are rewarded with knowledge that will let them use a very uniform language without fear of architecture-imposed performance problems.
Such knowledge is freedom from worry, to a programmer.
How does double-checked locking compromise the thread safety? It doesn't at all. That's bullshit. Double checked locking is perfectly safe. Example:
The above code is perfectly thread safe, but avoids having to run synchronized code at all once the object has been created. Whether the overhead is noticeable is debatable, but the double-checked-locking pattern is thread-safe.
Daniel
Carpe Diem
That's an excellent example of what I consider the best rule for proper coding: make your goal as clear as possible. The code using array subscripting is easier for less-experienced maintenance programmers to work on and doesn't need to be replaced when you find a clever compiler does a better job.
You must be freking kidding right...? Sub-selects
and a working optimized join are still missing
from MySQL..
( and don't talk about the upcoming 4.X version...
It's still not copletely ready...
These are critical features needed in most apps..
and having to do shity work arounds is not the way )
Ok, what the guy says is correct, except for the fact that more temporary objects allocated on the heap don't matter on performance.
But, Java is still slow. Slower than other languages. Let me give you some examples:
1) there is still no Java-based office application suite (and even if there is one, it is surely not widely known). You know why ? Because Java is slow.
2) I recently tried to use Poseidon for UML design. It is written entirely in Java. When the diagrams got a little big, Poseidon was way too slow.
3) I've got JBuilder 4.0 on my home Athlon 650 MHz/650 MB RAM and it is slow to the point of being unusable. Ok, that's an old product but...
4) in work I've used JDeveloper 9 from Oracle. Latest edition. Very slow, to the point of being annoying.
All of this under Windows. Half of the blame goes to the developers, I am sure, because they did not try to optimize their algorithms/formats/whatever. Half of the blame though goes to the language itself, since it lacks many things that will allow it to be quick:
a) generics, first and foremost. It's another thing to directly access an array's items and other thing to cast it to the proper type at every access.
b) every object reference is a pointer. All objects are accessed via their pointer, which is not a simple pointer, but a reference-counted one.
c) The JVM. JIT has many goodies for some type of applications, but...
All these are for static applications, I have to say. For the web, it might not play a role.
I have a proposition to Sun: migrate your Java libraries to C++, and have them be 100% source code-level compatible across all operating systems. The Java's libraries are top-notch, it's performance that hurts it. Let Java call native C++.
My understanding is that the Java generics model is simply syntactic sugar over a bunch of casts (??)
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 code.
In addition, I've found that programmers can be Soooo lazy that even the 90/10 isn't true in practice. I've seen the same expensive mistakes happen all over nearly every page of a web app.
This is why so many intranet and internet applications seem slow. People put-off worrying about performance until the last step (just like they are told to). And then it might be too late.
Developers get lulled into thinking everything's fine. Seems fast enough to them. But they are one user. Hundreds or thousands of real users will hit their app. If it's just OK for one, it's probably not OK for hundreds. Even if things seem lightning quick to you, they may not be for the hoard.
In a lot of cases, performance can't be gained just by optimizing the little things here and there. In these cases, you often have to restructure how you approach things app-wide; you find yourself tweaking sections of almost every module. Or yanking out nice abstractions in favor of going bare metal. That takes even more time to do after the fact.
My rule of thumb with web apps is actually to:
- Worry about performance throughout development.
- Time all page responses.
- Work on a slow machine.
If you are developing a app, you will be irritated by a slow DB fetch, too many redundant fetches, or too much processing. YOU don't want to wait. YOU will be highly motivated to speed things up just for your own productivity. Budding performance issues will be detected early when structural changes are less expensive (if deemed needed). At the end of the project, you will be fixing bugs, not re-architecting for performance.dave
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.
In theory, but in reality, your premise is false. Run tests on REAL PROGRAMS.
You seriously do not know what you are talking about. Take a class or something, because you're way out of your league. I doubt you can really program in C++, because I don't think you understand object-orientation. I think you were programming C++ as if it were C. It sounds like your problems are a result of poor programming for OO.
The supposed examples you give are bullshit, and prove that you're fucking incompetent. There are tons of transaction-based systems in Java. I see no reason why you're application is that special. I've worked on ones that support millions of concurrent users, manipulating 50+kB files, at thousands of transactions per second. This is very common. Lots of programs do similar things. If it's not working, it's your fault.
I just had to reply to this, because your obvious ignorance (and associated arrogance) are really irritating.
Jesus of Nazareth did not die so we could enjoy eggs and chocolate bunnies!
Are you sure? Christians enjoy eggs and chocoloate bunnies because despite the attempts of many clueless religious nuts, Christianity did not succeed in stamping out the natural human instinct for enjoying life, in the form of festivals and celebrations in which everyone can share - not just those who believe that their life is controlled by an imaginary being.
Celebrations of renewal and fertility in springtime, involving common symbols such as eggs and rabbits, were widespread before Christianity came along, and they continue today. In one sense, your sig is accurate, in that Jesus of Nazareth has nothing to do with it, other than the fact that the churches that exploit his name co-opted other traditions as part of their relentless assimilation of followers. But in another sense, the sig is wrong, since based on his record, I suspect Jesus of Nazareth would have no problem with people enjoying eggs and chocolate bunnies, even - and perhaps especially - on the anniversary of his death.
Urban performance legend #1: Synchronization is really slow
I'm not sure about this. I read advice on the web saying the synchronisation was slow and so changed all instances of Vectors into ArrayLists in a program I was writing. The program is very simple and just reads binary data and translates into strings, yet making this change certainly made the program run a lot faster (about 5%).
Urban performance legend #2: Declaring classes or methods final makes them faster
Well, lets face it - it can't make them any slower, can it?
Urban performance legend #3: Immutable objects are bad for performance
When I use the in built JVM profiling for my program, I find that code in the String class is the largest bottleneck by far. The program does a number of string concatenation using '+', and changing this such improved things a fair amount, although doesn't stop the String class having the largest bottleneck. I'm using the Java 1.4.1 JDK tools - maybe commercial compilers & JVMs are better, who knows
Essentially, higher level languages should result in faster code than lower level ones, since the compiler has more scope for optimisation and also gets more information about what the program is trying to do, although this Urban performance legends article seems a bit shaky to me.
-- Mike
Much has been said about how this article makes claims and backs them up with nothing. So I decided to run some benchmarks of my own. Tested on both uniprocessor and SMP, with a bunch of different code paths, using the very latest JVM.
I tested the assertion that synchronization isn't all that slow. First, I started by writing a simple test that goes into a loop and does enough work to not be optimized away by the compiler, but no more. This test showed synchronization to be about 200 times slower on SMP and between 50-100 times slower on uniprocessor.
But, as the author states in the article, that's a contrived benchmark, so I won't bore you with the details. He claims that synchronization only adds constant-time overhead to a function, so that in any 'real world' function that does 'real work' the performance difference will be small.
Fine, I'm willing to consider that. So I rewrote the test so that each method invocation allocated a 1024-byte buffer, wrote data to the buffer one byte at a time, allocates a new String, parses the byte-buffer to Unicode, and calculates the hashCode of the resulting String. That's heavier than most of the methods I write day-to-day, so let's see how bad the synchronization overhead is?
On a dual-processor PIII-1266Mhz with 1G RAM and the latest (1.4.1_02) JVM with default settings:
10,000 iterations nonsynchronized:
0.67 seconds
10,000 iterations synchronized:
1.47 seconds
So even in functions that perform 'real work', synchronization REALLY IS expensive. More than the rest of the method, which is a fair amount.
Where does this guy get off claiming that slow synchronization is an Urban Myth when anybody with a decent grasp of the language and willing to invest a few hours running tests can prove him wrong?
Source code for the test can be found at:
http://www.lewisworld.org/~mark/Test.java
If Java were faster, that would still leave 100 reasons why it sucks.
.NET is any sort of an alternative.
Static typing. Variables that are not instances of classes. Classes that you cannot derive from, but if you forget to make your classes final, it's a security risk. Write once, test everywhere. Klutzy widget set, but Sun will not let you deliver anything but SWING with your IDE if you want it to have a Java logo on the box. It's outright war between Sun's installer and you-know-who's operating system to get things working/not working.
Clueless managers who have fallen for the hype.
I could go on. Really.
Note: I am not saying that
Perhaps the experts can comment on this one, but isn't one correct way to implement the thread-safe singleton example in the article as such:
c hTips/1 998/tt0120.html). These 'benchmarks' are like that 'chart makers' that give you x and y percentages just to make their case look good. And in most instances, it's a specific situation that is being dealt with, which could be such a minutia element, but makes for a good razzle.
class SomeClass {
private Resource resource = null;
public synchronized Resource getResource() {
if (resource == null)
resource = new Resource();
return resource;
}
}
On immutable objects (string vs. stringBuffer)
SUN itself claims that using StringBuffer is faster (e.g.
http://developer.java.sun.com/developer/Te
When facing a troll, you can do something called the "mirror test". If something makes sense when redirected at the person saying it, then it has no relevance to the conversion. Let's partake in this exercise:
You seriously do not know what you are talking about. Take a class or something, because you're way out of your league. I doubt you can really program in C++, because I don't think you understand object-orientation. I think you were programming C++ as if it were C. It sounds like your problems are a result of poor programming for OO.
The supposed examples you give are bullshit, and prove that you're fucking incompetent.
See, that was easy. No content. And what you say afterward makes me know you're full of shit:
I'll bite. What type of fucking system can process millions of users concurrently? Tell me, please. If you mean a stateless web app, then you're simply lying, because there is no concurrency going on for any significant percentage of those million cookies you have stored in a table somewhere. If you have a million concurrent users, then the data stored for each user can't be more than a few ints. If your user data isn't in memory, then it's not concurrent. That is, the user operations are not operating concurrently, and thus cannot said to be "concurrent".
You're right. It was my fault for using Java. Java does many things well, but when performance is an issue, Java should be the last choice.
I just had to reply to this, because your obvious ignorance (and associated arrogance) are really irritating. [See, that's the mirror test again.]
Depending on how your program uses memory, it could be that other standard sorts of garbage collection -- mark and sweep, for example -- actually peform faster than reference counting. This would be true if, for example, you have a small number of objects being referred to by a constantly-changing large number of pointers; then the reference-counting overhead would be enormous, while the mark-and-sweep overhead would be fairly small.
In situations where CPU time is more important than RAM usage reference-counting could also be suboptimal, as you may not want to delete objects as soon as their reference count drops to 0 (instead you might want to wait for a lull in CPU usage and let an idle-priority thread clean them up when convenient). This is especially true if you have lots and lots of small objects (the CPU overhead of deleting objects 100x/second might be large, and if they're 50 bytes each, the RAM overhead of keeping them around a bit longer before deletion might be small).
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
The Java Sources!
... hope classpath will not get stuck again !
...
With the new JSPA, now any body can reimplement compatible Java VM taking benefit of the JCK / RI.
Apache guys fight agains some Sun fellow to obtain this JSPA.
Now we will see if the GNU gurus realy want an open Java or still preffer to get locked on their C++
Tiger (the new upcoming Java) will be under JSPA. But will RMS and others noticed this is an oportunities to make things moves in the right way ?
Hope so
Yes, Java is not the best performing language in many cases (not counting cost/time of development and when predicitve/optimizing JVMs outperform C code). However, for the trivial shit you seem to be doing, it's more than sufficient.
You don't see me getting all upset over the performance of Java, because I've never had a problem getting it to perform (I've written telecom load testing tools in Java). I have rarely done any JVM tuning either, only when changing memory limits in the system. Since lots of other people can use it fine, you might want to consider that the problem is you, and not the language. Hell, you could use a Java to assembly compilation chain, and I'll bet your code would still suck.
Just accept the fact that you don't understand it. Not everyone can understand everything (some less than others). You've had problems implementing some relatively simple things in Java (the kind of stuff it's traditionally pretty good at). Stop trying to place the blame elsewhere.
Where Java really falls short is in numerically intensive computation (ie. the Monte Carlo simulation someone mentioned earlier), and in GUIs (deep inheritance hierarchies are the main culprit here).
You can call me a troll, if that really makes you feel better about yourself. However, that doesn't change any facts.
I hope that the above post is part of an elaborate joke. Otherwise, looking at this and the 455 other messages comprising the debate so far, I don't think /. is about to improve its its position in the 'where to come for Java enlightenment' stakes.
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 never be more than the physical memory actually available to the Java process.
2) Re: CPU cache: By the time a CPU executes compiled code, bytecodes are nowhere near the CPU cache (they were never near the instruction cache). The fact that the code was earlier produced from bytecodes is completely irrelevant. Furthermore, bytecode compilation is persistent - compiled code is never destroyed for memory management purposes.
3) Java and C++ optimizations: by definition, a Java JIT compiler can make all the optimizations a static compiler can make, and then some. This is because: a) the bytecode is the semantic equivalent of the source, so all source optimizations can be applied; b) it additionally has access to the complete code base, not just the equivalent of a single source file and c) it has access to the dynamic characteristics of a program, such as "branch taken" metrics, meaning that potentially indefinite refinements of the program structure are possible.
For those that are true seekers after knowledge, I think it is safe to say that your reading time will be better spent with Sun's papers on GC or VM design, starting here, and perhaps comparing mechanisms with those of LISP machines, Dotnet or the Parrot VM.
I also recommend getting up to speed with the new I/O, printing and regexp features found in 1.4 - a good start is Travis's JDK 1.4 tutorial, though it does not cover everything new.
.
Here's the code you need...
//Print 'c' to textbox inside this 'if' block.
for (i = 0; i cameraStore.size(); i++)
{
Camera c = (Camera)cameraStore.get(i);
if (c.isAvailable())
{
}
}
An online Starcraft RPG? Only at
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:
Online Starcraft RPG? At
Dietary fiber is like asynchronous IO-- Non-blocking!
Java is interpreted (compiles to bytecodes)
C# is interpreted (compiles to MSIL or whatever they call it today)
Why my program (heavy on encryption) is 10-12 TIMES slower in Java version vs. C# version?
Code is identical.
Is it simply because Microsoft did a better job with the virtual machine?
I'm using JBuilder 8 this week. It's as good as any other desktop application on my Thinkpad R32. Sometimes I demo it to people and the coup de grace is always "... and it's written in java." which is usually responded with "but... I thought java was slow!".
Bad interactive java is easy to write, just like bad MFC applications are easy to write.
(sigh)
There are no karma whores, only moderation johns
Java has some brilliant profilers. JProbe is the one I use, but I hear that OptimizeIt is good as well.
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.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
The problem with this is that it's almost impossible for regular developers to "hand-optimise" their code effectively on any platform today.
Sure, you can write in raw assembler, or you can write in C and be careful of low-level details. But the instruction sets and performance characteristics of modern processors are so counterintuitive at times that usually you're just second-guessing the chip designers, and often you'll be wrong as a result.
There are people who are paid to understand how all the nitty-gritty pipelining, cacheing, and other tricks work in modern processors. They are compiler writers and library implementers. Few other people have the time and resources to invest in acquiring the same level of expertise. Most of us would be better off using a language that is of a generally suitable nature and letting the compiler/interpreter/JIT compiler/optimiser do its thing.
By the way, did you realise that some really quite high level languages now compile down to give more efficient code than C a lot of the time? Why? Because they provide high level features with good underlying implementations that are carefully designed around the target architecture. With a clean programming model, they can often optimise a lot of apparent work away as well. Using a low-level language like C denies the writer of the compiler/optimiser the same degree of assumption, so they can't help you as much as a HLL compiler/optimiser can.
For example, Intel's x86 series chips have REP and CMPSx instructions that seem to be carefully designed to work with strings. Do you know what you see if you look at typical strcmp code in any recent C standard library implementation, though? It looks like a whole mess of random assembler, several lines long, because it's been tuned to the specific target architecture's characteristics. It doesn't look like REP CMPSB.
The whole argument about using low-level languages for efficiency starts to break down around this point. In fact, it's all backwards. The higher the level of language you use, and the cleaner its programming models, the more the compiler/optimiser can help you to get efficient output code. In today's world, you use low-level languages for control and flexibility, but unless you really are an expert on your target architecture, you don't use them for efficiency.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
Yeah they do. If it's a lot of time. If it's just more than it should have been in that scenario, then no, practically no profiler gives you any idea; it just gives you the average time spent in that routine, not the worst case AFAIK.
-WolfWithoutAClause
"Gravity is only a theory, not a fact!"The author of the linked article gives a nice neat (though perhaps not intentional) summary of why Java opts take on an almost "urban legend"-like status:
In C, or just about any truly compiled language, you most certainly can measure the performance of two different ways of doing something.
Then again, this counts as one of the many factors in the C-vs-Java wars... C programmers like determinism. Java programmers like idiot-proofness. If you need to factor in the amount of time it takes to unload the gun in "point at foot, pull trigger", you'll never really get a good idea of how long it takes to "shoot self in foot".
I wrote a fractal planet surface generator in java. It spat out a gif image 2000 pixels by 1000 pixels, doing about 8 floating point operations on each pixel... so ~ 16,000,000 operations, not counting the gif encoding.
The whole thing ran, from scratch, on my ancient 450Mhz PIII in *under* a second.
But loading the resulting gif into a paint program to look at it was a pain... so I added a swing display class...
Suddenly it took ~ 5 seconds to run!
So I trimmed code, until I was back to a 'hello world' program in swing. ~ 3 seconds.
This is generally my experience; java is reasonably quick for data processing (not ultra-quick, but not too bad), but Swing and the GUI stuff let it down big time. I've heard IBM's swt stuff is good, but haven't tried it.
Oh yeah, and most of the article seems like bullshit. I've seen bulk benchmarks showing the opposite of what this guy says, and I'm too old to believe proofs by assertion any more.
Wer mit Ungeheuern kämpft, mag zusehn, dass er nicht dabei zum Ungeheuer wird.
Echidna already does this. Also, see my other comment.
Mark and sweep doesn't use reference counting. The mark stage looks at all pointers (references in Java), follows those pointers (and anything pointed to by the targets of those pointers) and marks all the things it finds as "reachable." Then the sweep stage goes through memory and deletes everything that wasn't marked as reachable.
In the case I mentioned (not many objects but constantly-changing pointers to them) this could have lower overhead, because you only do the mark stage periodically, instead of having to update a reference-count variable every time a pointer to the object changes (which could be potentially millions of times more often than the mark-and-sweep GC runs).
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
...is that Java is an excellent and fast language.
jEdit is the best text editor I've ever come across. I wasn't looking for a java app, merely a free text editor that would allow me to easily define my own syntax highlighting (for an obscure scripting language for a data acquisition tool that still makes me shudder when I think about it). that was nearly 3 years ago and I've been using it every day ever since. it's editing features are superb, it's endlessly configurable and is extensible through its plugin mechanism to the point of being a fully-featured java IDE. the performance is good enough that I the fact that it's java is a non-issue. it just isn't something that I have to think about. I'm not claiming that it's as fast as it would be if it had been written in C++, nor am I claiming that java / swing is the perfect solution for all desktop apps (it's certainly not) but it IS a very useful java desktop application that I use 8 hours a day every working day of my life.
If each tape measure weighs 11 ounces, how long is a piece of string?
To be fair, the template method needs to be compared to this java code:And similar C code to be compiled with icc or gcc.
For extra speed on the java side, you might even try storing the result in one of those fancy new LongBuffer objects, or, since here we have a limit on what we're calculating, a simple long array.
But at this point it's silly - template metaprogramming wins here because it is (behind the scenes) using a better algorithm.
Which, I suppose would not be an overly bad lesson to take away from this: templates can do things faster because they transform into better algorithms behind the scenes. However, even though I believe that statement to be true generally, I still think that this example is cheating, as the memoizing that templates do for you is often not going to be what you want.
For reference, the perl that uses this is:
According to this article on theserverside.com, in one person's benchmarks, .NET is slower than Java. YMMV and all that.
it's not going to stop until you wise up, no it's not going to stop. so just give up.
Collect all the Java programs you can get your hands on.
Throw them in the garbage.
Problem solved.
I am serious!
In trade, one thing you might consider allowing is several constructors of the form:Then, you could replace common idioms like this:with:(And yes, you should also be using log.isDebugEnabled() if your logging facility has that)
The advantage of this idiom overis that you don't have to get that "80" constant right in order to avoid potentially expensive re-allocating.
Of course, at this point it might well be worth it simply to have a class with a static function called "BetterStringConcatenation" or similar which is overloaded similarly (i.e. to take a huge number of different objects) and simply returns the string made by concatentating the right ones together.
The step after that is to hack a java compiler (e.g., jikes) so that it uses your BetterStringConcatenation internally whenever + is used for string concatenation... hrm...
So much for the language that removes all those nasty things that stoopid programmers get wrong. You still have the issue of equality of value vs. equality of identity, you just have nastier syntax for it.
Sure. Just as it's obvious that you don't start coding serious C++ without knowing the RAII idiom, you don't start coding serious Perl without understanding the caveats of eq vs. ==, and you don't start coding C without knowing that gets is fundamentally flawed. Except that actually, many people do.
I'm afraid your post actually stands against one of the biggest myths of them all: that Java is much safer than other comparable languages, notably C and C++, because of the limited feature set it provides. The reality is that you can still screw up in Java, and it really isn't much harder than in any other language of a similar level. There are good reasons to use Java for many projects, but immunity from developers who haven't done their homework ain't one of them.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
This is why so many intranet and internet applications seem slow. People put-off worrying about performance until the last step (just like they are told to). And then it might be too late.
Good point. At the end when everything is working fine, you manager might say something like "everything is working just fine. Why do you want to spend the next two weeks on performance issues? I have more higher priority things for you to do".
The old myth that floating point operations are slower than integer is wrong too. We tested that one 5 years ago and a floating point operation of the same values often beat the integer operation.
Very interesting. I would think that since floating point storage is greater than integer storage (at least on 32-bit PCs), the speed would automatically be better for integers. Can you give more information?
Why you might make some good theoretical points, some of your assumptions are off. I heartily recommend to you reading Sun's java manpage and searching for the word "default" before making statements about what the default behavior of java is.
By default java will limit the heap size to 64 MB If, as with most modern machines, you have significantly more than 64 MB to devote to user-mode applications, then the default settings will not in fact, as you contend, make performance horrible the instant more than one java application is launched. Also, keep in mind that with java, the JIT can if it wishes to do so move frequently accessed objects so that they are on adjacent pages of memory. This can dramatically reduce paging latency as compared to other code.
As for your points about L2 and L3 instruction caches - I suppose. At the very least, I don't know of any reason why it is obviously false. I'd need experimental confirmation first before I'd be willing to accept this.
I think that the real reason that swing is single threaded is because it's easier to program with if you only have one thread dispatching events and doing drawing.
That way the application programmer doesn't have to bother with syncing on the data properly.
Say that you had one swing thread that dispatched events, and another that only drew the screen.
Fine and dandy right? Well this is a PITA for all application programmers. While this will probably give you maximum responsiveness to the GUI, it's also the larger source of problems for a programmer who doesn't know anything about multi-threaded programming (like most people).
First off you must sync on every change an event causes to the data that is accessed for drawing. Any data that the drawing code requires must be locked before modification. The other choice is to copy ALL display data and then fire it off to the display thread, not the best idea in the case of say, JTables.
Secondly, the likleyhood for deadlock is high. Of course there would be defined protocols for locking on shared objects between the display and event threads, but programmers would either be ignorant of them or ignore them. (but it runs faster! even if it doesn't work half the time)
Swing is IMO designed well but it suffers from bloat. Bloat of having the AWT beneth it and bloat from having to run on ANY platform. This causes it's responsiveness to go down overall.
As far as running multiple independent applications at the same time in on JVM, it's possiable but you have to re-write the AWT shared classes (like Toolkit) so that they expect it. With the ability to have multiple event threads for seperate applications and also you would probably have to create a generic library for sharing data among the different applications. I wish it were as easy as creating different class loaders for each seperate application, but the Native code assumes only one event loop per application, and dlls can not be dynamically loaded in the same way as classes. ( they cannot be linked to multiple times, while you can load multiple versions of the same class with the class loader)
BTW, the Swing event loop and the AWT event loop are the same.
1: Synchronization.
This is slow. Really slow.
I think your test was flawed. Please see here for a test showing one popular usage of synchronization (lazy initializers). One million cycles takes about 30 milliseconds longer (a hair more than twice as long) for the synchronized version as for the fastsynched (effectively unsynchronized after the first call) version. Unsynchronized actually came out slower, showing that compiler behaviour is probably a bigger issue.
30 milliseconds per one million cycles. The extra 6 lines of code (and their extra defect opportunities) cannot be justified in any but the most extreme performance optimization situation.
Stop-Prism.org: Opt Out of Surveillance
ROTFL... Here's my mod points when I need them....
if (!signature) { throw std::runtime_error("No sig!"); }
hear, hear, so true, used profilers for the first time at my old job. Was a dream to use, managed to increase the performance of my app (comm app tx/recv SMS messages) from 5 msgs/sec to ~50 msgs.sec. not bad. Should have been able to squeze out more, but that would have been pretty much a complete rewrite plus our database wouldn't have been able to cope with much more anyway(ppl apparently got it up to ~400 msgs/sec, but that's the Big Boys, read: Mobile Network Providers).
if (!signature) { throw std::runtime_error("No sig!"); }