"It’s not as slow as it used to be, but it’s still pretty un-optimized. It doesn’t run “close to the metal” like C and assembly does."
While everyone likes to have efficiency, being readable and/or easy to use sometimes trumps it. Would you really write a program like <insert large Java program here> in assembly, just because it would be faster?
I'd go further and say that readability and/or ease of use _often_ trumps efficiency. I/O tends to be the bottleneck at least as often as CPU, apart from anything else.
I agree with the point about writing in assembly language. This rant is basically arguing for speculatively micro-optimising _every line of code_ by choosing a supposedly faster language.
I'm the author of the original post. The article isn't about optimizing every line of code, it's about not being lazy and choosing a language that you might have to do a little more work in for a massive decrease in bloat and execution time. One tool isn't always the right one for every problem. Don't use a hammer to screw in a screw. Sure, the screw will go in, but with just a little more effort (using a screwdriver) the task will be done much better. It's about wasting money & resources because a programmer doesn't want to write a little extra code to manage memory or watch return codes.
I'll put it another way. Most code isn't performance-critical. If you choose to write everything in, say, assembler, most of it will give you little or no gain. Assembler's harder to write than Java, so every line is costing you money, whether it actually runs faster or not. The _effect_ is the same as speculatively optimising every line: substantial cost, uncertain benefit, potential to introduce bugs, etc etc.
The thing about efficiency is that efficiency from one person's perspective is not the same as efficiency from another's. It may _run_ more efficiently, but maintenance efficiency decreases and extendability efficiency increases. So, you've traded a marginal short-term gain for long-term decreases in efficiency.
It's weird to criticize Java for being slow. These days it's pretty much As Fast as C, unless you have a huge amount to gain from unboxed arrays of non-primitive types, or manual memory management. (Possible, but not terribly likely.)
The JVM has never been 1000x slower than native code. Fourteen years ago it was occasionally as much as 10x slower. What's the penalty these days, maybe 10%? And in return we don't risk undefined behavior if anyone who worked on the project ever made a single mistake? Java is a mediocre language at best, it truly epitomizes everything pg said about Blub, but I'm still glad we didn't use C.
And assembly? Seriously? All but the tiniest processors are superscalar now, and the performance of code depends on obscure details about how instruction scheduling fits into pipelines. The way I hear it, there are only a handful of people in the world who can actually do that better than their compiler, and I'm not going to become one of them. There are too many other things to learn that I can keep using over more time.
I'm the author of the original article. What about bloat? It's hard to compare java to C applications because people don't tend to write the exact same app in more than one language, but compare Azurus to utorrent. Sure, Azurus has many more bells and whistles than utorrent does, but are you willing sacrifice an entire machine's CPU/memory to a single app just to get some special features? I doubt it. utorrent is the most popular torrent client because of this very fact. If Azurus weren't just a resource hog, it would be the most popular because of its features, but it isn't. People don't need a million features. They want an app that runs quickly and efficiently and gets the job done.
The same thing with web app development. Just because you work for a company with a huge budget doesn't mean that you should squander the company's money on hardware when it could be done with less. If your whole programming department thinks that hardware is cheap, then before you know it you've got 500+ machines to run a simple website. We're no longer talking pennies here. We're talking hundreds of thousands of dollars and tens of thousands of dollars monthly. That would hire a whole staff of C programmers.
There exist many C libraries that provide the same functionality that java provides. You guys should just bite the bullet, commit yourselves to doing a little manual memory management, drag out your favorite debugger and try writing you next app in C or C++. I'd bet that you'd be very surprised at how very do-able, writing a current-day app in C or C++ actually is compared to java.
Come on, where are my fellow C programming brethren? I know you're out there! Take a break from your desktop app coding and back me up on this! :)
Somewhat tangentially: I run a useful app, JBidWatch (a nice, free eBay "sniping"/monitoring tool) on my Windows XP desktop. I started it 1 week ago following a reboot. One week later I noticed the PC's mem usage was nearing the amount of physical memory and investigated; one contributor turned out to be the JVM session running this app: according to Task Manager, this app (actively monitoring no items during the week) was consuming over 100M of memory. Now, I won't stop using it, because I'm not aware of a better tool, and restarting it is not particularly painful, and yes, it's likely this app wouldn't exist w/o the ease of programming offered by Java (though I would prefer a GUI-less version written in a language I am fluent in), but still: 100M of memory for a web-polling app that was essentially idling (from an end-user perspective)? I've observed that various JVM apps gravitate to these (to me) giant memory footprints over time; I assume it's "the nature of the beast", but I'm speaking as a programmer who has never written a line of Java. A sysadmin sitting in the next cube, responsible for various Java-based server apps, has simply agreed with me that this is what's expected from Java apps.
This sounds like a memory leak (probably sticking items in a hashmap and never bothering to remove them), or nothing has forced a major GC. Java apps that grow in memory usage without bound aren't demonstrating problems with Java - they're demonstrating poor programming. JIT'ing and GC algorithm improvements over the past few years have invalidated a lot of the original complaints raised against Java.
The anti-GC part of this rant is especially hard to take. I've had the misfortune of having to debug various memory allocation problems in C. That's something I don't miss at all. To bag GC for performance without mentioning reliability is just wrong.
The weird thing is how many projects resort to reference counting, which is just like GC only far more expensive (now every single p1=p2 requires two checks for null, an atomic increment and decrement, and a conditional branch around a dtor call!) and less reliable.
It seems to me like the endgame of most memory management problems is static buffers and pools for speed/low fragmentation, and GC for everything else; manual allocations are just too fiddly for most coders to favor them for optimization.
Disclaimer: I've mostly worked in GC environments.
You say reference counting is far more expensive, but that's only in CPU cycles. Compare Python (reference-counted) and Java (garbage collected), and Java's memory use is 3x greater for similar programs, at least in my experience (also in the computer language benchmark game). Reference counting is a form of garbage collection, it's just eager rather than lazy, and that eagerness pays off in predictably lower memory usage.
You can save memory by writing a file a byte at a time rather than allocating a buffer. The reason you don't is that it's more efficient to batch that work. Well, the same is true of GC. If you have a million dead objects and a thousand live ones, doing bookkeeping for each dead object is far more expensive (in cycles and bus bandwidth) than just having a copying collector rescue the live objects and then reuse those memory pages en masse.
Once your program's memory footprint is small enough to fit on the machines you're using, making it smaller takes more runtime work but has little benefit.
I'm the author of the original post. It's not difficult. Get a good debugger, and you're job is easy. Use a memory allocation tracker while you debug, then switch back when you're done. It's not hard, just takes a little more time. Don't be lazy. Use ccmalloc: No recompilation is needed to use ccmalloc; simply link it with -lccmalloc -ldl or ccmalloc.o -ldl When you've found and fixed your leak, stop linking with the library and you're done. Why switch to a GC architecture because you don't want to do something easy like this?
I wasn't just talking about memory leaks. Memory allocation in C is a rich source of bugs. Even assuming they are "easy to fix", that's still a poor second to "never happened in the first place". GC isn't free, sure, but it has definite advantages.
I can't really tell if the author is joking (it reads a little sarcastically), but assuming he's not, the counter argument is really easy. While you're spending days writing mallocs and copying function pointers in C, your competitor is using one of these "lazy programmers" languages and implementing features in hours. Features that are going to take you days to write. Once scale is needed, your competitor just goes out and spends $700 on a cheap server and matches your performance. Ultimately it comes down to time vs. money. It sounds like the author still thinks all computers cost hundreds of thousands of dollars.
The key words to understand the author are buried in there: "As a sysadmin".
For sysadmins, the time saved in development means nothing, while every additional machine (and especially the infrastructure to run them as a cluster) means more work.
Still, shouldn't even a sysadmin appreciate the increased reliability and especially security that modern languages bring?
Exactly, as a sysadmin, he should appreciate, that he is not solving buffer overflows all the time.
Regarding the more work, as a sysadmin, it is his job to make the machines run the application.
His salary and benefits are part of the cost using the higher level languages/additional computers. His rant could be taken as "lazy sysadmin" problem, while what he is ranting against was just costs/benefits decision.
I'm the author of the original post. Sysadmins don't solve buffer overflows, that's a programmer's job.
True, my rant could be takes as a "lazy sysadmin", but I have a CS degree and have a programming background. Personally, I'd prefer to re-write this code myself in C than see this kind of hardware waste. That's not being lazy, it's being respectful of the power at my disposal. Use the machine's power on doing actual work, don't waste the machine's power on programmatic overhead that could be avoided by making a different choice.
Sorry, I was inprecise. Of course sysadmins do not solve buffer overflows, they solve what happens when someone exploits one.
I understand what you are saying, you see that the flight to the moon was done by something equivalent to C64 and today we are allow wasting orders of magnitude more computing power.
What I'm trying to tell you, look at the whole picture. There is a cost associated with writing and maintaing software. That hand optimized assembly application is going to be more expensive (and take longer to deliver) than the Java/c#/whatever equivalent. There is another cost associated with purchasing and operating hardware (that includes paying sysadmins, for example). The business has to consider what is more effective, and usually HL language/more HW is the more efficient solution.
What, more efficient, you say? We were talking about wasting the computer power. Yes, more efficient overall. We have a method for measuring wasting resources - money. You are going either waste some money on hardware/electricity/floor space/sysadmins, or programmers/time to deliver/managing larger team/managing recruiting and retaining competent programmers. Not only is the former cheaper, it is also easier to quantify and manage. It is no wonder, that you do not see companies taking the later approach.
At the end, what most people do not understand (not only technical people, but most people) is that successful enterprise is not a 100% efficient one. There is going to be waste, but it must be in the right spot. Actually, conceptually it is similar to profiling, you don't optimize spots that do not matter in the big picture. And computing power does not matter for most business, it is a cheap resource. People, on the other hand, is not.
I'm the author of the original article. A typical server costs $1500 (DELL, HP) nowadays, but I've seen java apps commonly take up a whole rack of servers, not just one. This is a base cost of $30k and > $1500/mo for rackspace, A/C, power, bandwidth and maintenance. That's one-half of an FTE up-front and one FTE's salary reoccurring.
I hear from java developers, "I'll need 6x 3Ghz, quad-core, dual-cpu machines for this (pretty simple) app I'm writing". Are you f-ing kidding me? Do you know what you could do with that kind of hardware if you wrote it in a different language? Your app is basically a glorified web server that does one thing that apache doesn't do out of the box. It sickens me to see this kind of waste because of the programmer's language choice.
That's one-half of an FTE up-front and one FTE's salary reoccurring.
Only if your FTEs are very cheap. Most I know wouldn't get out of bed for less than $50k+.
But even if it was half a man-year upfront and one recurring - that's still a no-brainer (remember we're talking an entire rack here, which goes quite a way for most apps). If that rack enables your 5 programmers to work only 10% faster (completely theoretical ofcourse, but for the sake of the argument...) then it has already more than paid for itself.
Your argument is quite old nowadays (I remember the heated efficiency debates in the 90s) and has long been decided. Hardware is so cheap now that in most cases it really is demonstrably more cost effective to throw hardware at certain problems.
It depends on the constants. For example, we rewrote our critical path app server in Java, and now it can handle 6x the load compared to our predecessors' PHP version. Twitter was getting crushed by Ruby performance, so they went to Scala on the JVM. These were clearly worth doing. But using C would only net a few more percent in performance and at best 50% less memory required, at a huge stability risk.
Rather strange rant. I hope it was trying to be funny, but if so, it failed miserably.
Anyway, what I find interesting is that Java really is very slow in one thing: startup time. My completely unscientific test concluded that a hello world -program in written in Java takes about 0.110 seconds to run, while the C version took about 0.003 seconds. What's interesting, Python version takes about 0.015 seconds, which includes parsing, compiling to bytecode and interpreting it, while the Java version has already been parsed and compiled. I would like to know what explains this almost tenfold difference between Java and Python startup times. I suspect it might have to do with the security features of Java?
I'm the author of the original post. cross-platform benchmarks like this typically don't represent real-world apps. They're usually tiny benchmarks that test one or two things, but don't really hit the nail on the head when it comes to resource bloat or garbage collection or things that happen to an application that runs for days, weeks or months at a time. Yea, startup time is going to be faster in C or C++ because there isn't anything to start up. C just starts running and after the OS has the application scheduled, it starts doing real work, not pre-allocation of things and all of the overhead that's involved with languages like java, python, ruby, perl, ... For small applications, startup time is important. In unix/linux, when you string a bunch of apps together on a command-line, startup time is very important. So, don't dismiss startup time.
Secondly, let's talk socket pools, file handle pools, garbage collection, and all of the many things that java gives you to get better performance out of a language that is literally the elephant (bloated, slow thing) in the room.
I'm the author of the original post. Re: login, sorry, it's drupal and I turned off anonymous comments for spam reasons. :)
I'm sorry that you think that I'm naive. I'm 41 years old and have a CS degree. I've been a linux programmer and sysadmin since 1993, before linux had a 1.0 kernel (0.99.9.45 or something like that when I installed my first linux machine). My background is in programming and I spent my college career in 1990-1994 writing mostly C code.
Java is slow, although most java programmers don't want to admit it. When you take into account resource bloat, java is still a horrible choice for almost any application unless you work for a company with a lot of money that's willing to just throw money at hardware because the software developers say it's needed.
If you'd like to compare apples-to-apple, it's going to be hard because people don't usually write the exact same app in more than one language unless they're doing benchmark tests of something simple (usually hello world, or a matrix operation or something), but not real world applications.
I realize that I'm sticking my neck out there for criticism, but I'm ok with it. A lot of web programmers are java engineers - young kids coming out of school with a java background and they don't want to even deal with C because they don't want to do the manual memory management or watch for return codes, but instead just wrap the whole function in a try/catch handler. To me, it's laziness. C and C++ are almost the same syntactically to java. You guys can write C or C++, you just choose not to. For me, being a sysadmin for a living now, this is just a lazy and wasteful choice.
If you were to write your code in something more "close to the metal" just think how much more awesome your programs could be!
No, it's not. Modern JVMs produce extremely fast code. For numeric calculations, there's essentially no difference in speed between Java and C. (After all, why would there be? The JVM has static type info and is emitting assembly.) This was true even in 2004, so it's really long overdue that you move on from 1995 :)
In many cases macro-optimization trumps micro-optimization. C/C++ might be closer to the metal and in extremely simple applications incrementally (or perhaps significantly) faster, but if the difficulty of using C for web app development results in an extremely sub-optimal solution then you'd have been better off with a more advanced language like Ruby or even Java.
Moreover, the long pole in almost every web application of any significance today is the database. Whether you're using C++ or PHP is irrelevant if just waiting on a SQL statement to execute dominates the performance of your app by an order of magnitude or more.
Additionally, there's frequently a lot of room for optimization in any web app. Techniques like CSS spriting, serving static content from a cookie-less domain, and aggressive caching can make far more of a difference to overall performance than choice of language.
Finally, throwing hardware at the problem almost always makes sense as long as you can get away with it. A $1500 server is roughly equivalent to the cost of a single day of development for a talented team of only 4 devs (keep in mind that the cost of employing developers includes not just their base salary but also other costs like administration, 401k matching, health insurance, payroll taxes, etc, which nearly doubles the nominal per hour cost). Until you're perhaps $20-50k in the hole it probably doesn't make sense to consider putting serious effort into re-engineering your software from the ground up for scalability.
I'm the author of the original post. I agree that I/O is going to be slow in any language, so I agree with you there. However, your point about a single server being equal to the salary of 4 FTEs, in my experience, we're not talking about a single machine. Commonly, we're talking about dozens or racks worth of machines. Now we're not talking pennies anymore. We're talking tens of thousands of dollars. This is wasteful of our current massively-powerful machines.
Now we're not talking pennies anymore. We're talking tens of thousands of dollars.
Do the math. If 4 devs cost $1500 in a day then "tens of thousands of dollars" is not much in comparison. I think you, like many devs including myself, might be suffering from "big figure anxiety". A $50k investment for a rack looks mighty intimidating at first. But break it down in excel and in most cases you'll find it turns out way cheaper than the alternatives (e.g. hiring a few "C experts" or "spending a month on optimizations").
Let's say that servers cost $1500 each and a rack of 20 servers costs $1500/mo for hosting costs. Programmers make $80k/yr. Let's also say that C is twice as slow to develop for and let's say that Java requires twice as much hardware to run.
One java programmer writes an app that takes a rack of equipment to run and writes it in 6 months. Meanwhile, a C programmer takes 12 months and only 1/2 rack of machines.
After a year, the java app costs $40k in programming costs and an initial cost of $60k for hardware, so $100k. A year later, hosting costs rack up another $18k. The C app costs $80k in programming costs, $30k for hardware, so $110k. A year later, hosting costs rack up another $9k, so we're about even. You may argue that C takes > 2 times to write, and I will argue that java bloat requires more than a 2x hardware purchase, so we're talking pretty much a wash here. I don't think that your cost argument holds much water.
You're missing the key points. The most important determining factor for the hardware footprint and overall throughput performance for the vast majority of web applications is not in the front-end but in the database. It doesn't matter if you write your front-end in C, PHP, or even LOL code the database calls are still going to dominate the hardware needs and performance characteristics of your application by a factor of 10-100. Spending your entire development budget to shave 10% or 1% of your hardware and performance overhead down to 5% or 0.5% is silly, which is why nobody does that.
Moreover, going down the list of low hanging fruit in terms of reducing cost and rendering time per page-view the option to switch to a "more efficient" language is so far down the list that it's almost never reached. Indeed, it's often more important to switch to a language that makes it easier to scale out to more hardware than it is to switch to a language which is abstractly faster at individual optimizations (again, macro-optimization trumps micro-optimization). The biggest performance improvement efforts tend to be orthogonal to development language entirely. For example, tuning your database design and DB server parameters, using extensive caching, cutting down on http request overhead, etc.
It's telling that a company like facebook (which has no shortage of developer talent) chose to spend its efforts on making PHP faster by building a new compiler for it rather than moving away from PHP to some other hypothetically more efficient language.
Efficiency is an important factor in web development, it can affect end-user performance, costs, and profitability. But it's rarely as significant as many people make it out to be. It's more important to build something that people care about than it is to build something extremely efficient. For the vast majority of sites, increasing the popularity of your site by 10-100x is far more important than reducing the server footprint by 2x, or even 10x.
Well, I can only second what InclinedPlane already said and would like to add: While your idealized calculation [naturally] supports your point, it doesn't match up with what I've seen in reality.
In most companies you don't have one programmer per rack but many programmers per rack. The hosting costs are usually dwarfed by the programmer salaries, often as much as to make the former appear as a rounding error.
Consequently you should in almost all cases optimize for developer-performance, not for software performance.
I think the source of the OP's pain can be traced to the fact that while Java is reasonably competent as a programming language, it's complete and utter crap as an operating system. It replaces the finely honed tools of a modern operating system with it's own inferior versions, the process model is replaced by threads, shared libraries are implemented as "Beans" and come with an impressive armature of support infrastructure that could be dispensed with in favor of a simple configuration file.
Sadly, it is the faults of java that pre-adapted it to success in a corporate environment; it creates an impression of vast complexity in even simple tasks and allows for large budgets and swollen headcounts that translate into more power for the leadership of projects in which it is used.
47 comments
[ 3.4 ms ] story [ 76.1 ms ] threadWhile everyone likes to have efficiency, being readable and/or easy to use sometimes trumps it. Would you really write a program like <insert large Java program here> in assembly, just because it would be faster?
I agree with the point about writing in assembly language. This rant is basically arguing for speculatively micro-optimising _every line of code_ by choosing a supposedly faster language.
And assembly? Seriously? All but the tiniest processors are superscalar now, and the performance of code depends on obscure details about how instruction scheduling fits into pipelines. The way I hear it, there are only a handful of people in the world who can actually do that better than their compiler, and I'm not going to become one of them. There are too many other things to learn that I can keep using over more time.
Disclaimer: I've mostly worked in GC environments.
Once your program's memory footprint is small enough to fit on the machines you're using, making it smaller takes more runtime work but has little benefit.
Easy for a sysadmin to say! How many web apps have you written in C lately?
> It's not hard, just takes a little more time
Yeah -- just long enough to go out of business ;)
Here is a decent reddit thread discussing why people don't like Java: http://www.reddit.com/r/programming/comments/9dzpu/ask_reddi.... The most succint answer just links this: http://ws.apache.org/xmlrpc/apidocs/org/apache/xmlrpc/server...
For sysadmins, the time saved in development means nothing, while every additional machine (and especially the infrastructure to run them as a cluster) means more work.
Still, shouldn't even a sysadmin appreciate the increased reliability and especially security that modern languages bring?
Regarding the more work, as a sysadmin, it is his job to make the machines run the application.
His salary and benefits are part of the cost using the higher level languages/additional computers. His rant could be taken as "lazy sysadmin" problem, while what he is ranting against was just costs/benefits decision.
True, my rant could be takes as a "lazy sysadmin", but I have a CS degree and have a programming background. Personally, I'd prefer to re-write this code myself in C than see this kind of hardware waste. That's not being lazy, it's being respectful of the power at my disposal. Use the machine's power on doing actual work, don't waste the machine's power on programmatic overhead that could be avoided by making a different choice.
I understand what you are saying, you see that the flight to the moon was done by something equivalent to C64 and today we are allow wasting orders of magnitude more computing power.
What I'm trying to tell you, look at the whole picture. There is a cost associated with writing and maintaing software. That hand optimized assembly application is going to be more expensive (and take longer to deliver) than the Java/c#/whatever equivalent. There is another cost associated with purchasing and operating hardware (that includes paying sysadmins, for example). The business has to consider what is more effective, and usually HL language/more HW is the more efficient solution.
What, more efficient, you say? We were talking about wasting the computer power. Yes, more efficient overall. We have a method for measuring wasting resources - money. You are going either waste some money on hardware/electricity/floor space/sysadmins, or programmers/time to deliver/managing larger team/managing recruiting and retaining competent programmers. Not only is the former cheaper, it is also easier to quantify and manage. It is no wonder, that you do not see companies taking the later approach.
At the end, what most people do not understand (not only technical people, but most people) is that successful enterprise is not a 100% efficient one. There is going to be waste, but it must be in the right spot. Actually, conceptually it is similar to profiling, you don't optimize spots that do not matter in the big picture. And computing power does not matter for most business, it is a cheap resource. People, on the other hand, is not.
Only if your FTEs are very cheap. Most I know wouldn't get out of bed for less than $50k+.
But even if it was half a man-year upfront and one recurring - that's still a no-brainer (remember we're talking an entire rack here, which goes quite a way for most apps). If that rack enables your 5 programmers to work only 10% faster (completely theoretical ofcourse, but for the sake of the argument...) then it has already more than paid for itself.
Your argument is quite old nowadays (I remember the heated efficiency debates in the 90s) and has long been decided. Hardware is so cheap now that in most cases it really is demonstrably more cost effective to throw hardware at certain problems.
Ok, and I've seen Java apps not do that. Argument by anecdote is bankrupt.
Anyway, what I find interesting is that Java really is very slow in one thing: startup time. My completely unscientific test concluded that a hello world -program in written in Java takes about 0.110 seconds to run, while the C version took about 0.003 seconds. What's interesting, Python version takes about 0.015 seconds, which includes parsing, compiling to bytecode and interpreting it, while the Java version has already been parsed and compiled. I would like to know what explains this almost tenfold difference between Java and Python startup times. I suspect it might have to do with the security features of Java?
Secondly, let's talk socket pools, file handle pools, garbage collection, and all of the many things that java gives you to get better performance out of a language that is literally the elephant (bloated, slow thing) in the room.
Wins prize for most naive rant this week. There are a lot better reasons to hate on java, but speed really isn't one in 2010.
I'd love to see the rewrite of one of the apps he's complaining about in C and blog post about that.
--omg-optimized
I'm sorry that you think that I'm naive. I'm 41 years old and have a CS degree. I've been a linux programmer and sysadmin since 1993, before linux had a 1.0 kernel (0.99.9.45 or something like that when I installed my first linux machine). My background is in programming and I spent my college career in 1990-1994 writing mostly C code.
Java is slow, although most java programmers don't want to admit it. When you take into account resource bloat, java is still a horrible choice for almost any application unless you work for a company with a lot of money that's willing to just throw money at hardware because the software developers say it's needed.
If you'd like to compare apples-to-apple, it's going to be hard because people don't usually write the exact same app in more than one language unless they're doing benchmark tests of something simple (usually hello world, or a matrix operation or something), but not real world applications.
I realize that I'm sticking my neck out there for criticism, but I'm ok with it. A lot of web programmers are java engineers - young kids coming out of school with a java background and they don't want to even deal with C because they don't want to do the manual memory management or watch for return codes, but instead just wrap the whole function in a try/catch handler. To me, it's laziness. C and C++ are almost the same syntactically to java. You guys can write C or C++, you just choose not to. For me, being a sysadmin for a living now, this is just a lazy and wasteful choice.
If you were to write your code in something more "close to the metal" just think how much more awesome your programs could be!
No, it's not. Modern JVMs produce extremely fast code. For numeric calculations, there's essentially no difference in speed between Java and C. (After all, why would there be? The JVM has static type info and is emitting assembly.) This was true even in 2004, so it's really long overdue that you move on from 1995 :)
http://www.idiom.com/~zilla/Computer/javaCbenchmark.html
>If you were to write your code in something more "close to the metal"
C is close to the PDP-11; it's not particularly close to modern hardware.
Moreover, the long pole in almost every web application of any significance today is the database. Whether you're using C++ or PHP is irrelevant if just waiting on a SQL statement to execute dominates the performance of your app by an order of magnitude or more.
Additionally, there's frequently a lot of room for optimization in any web app. Techniques like CSS spriting, serving static content from a cookie-less domain, and aggressive caching can make far more of a difference to overall performance than choice of language.
Finally, throwing hardware at the problem almost always makes sense as long as you can get away with it. A $1500 server is roughly equivalent to the cost of a single day of development for a talented team of only 4 devs (keep in mind that the cost of employing developers includes not just their base salary but also other costs like administration, 401k matching, health insurance, payroll taxes, etc, which nearly doubles the nominal per hour cost). Until you're perhaps $20-50k in the hole it probably doesn't make sense to consider putting serious effort into re-engineering your software from the ground up for scalability.
Do the math. If 4 devs cost $1500 in a day then "tens of thousands of dollars" is not much in comparison. I think you, like many devs including myself, might be suffering from "big figure anxiety". A $50k investment for a rack looks mighty intimidating at first. But break it down in excel and in most cases you'll find it turns out way cheaper than the alternatives (e.g. hiring a few "C experts" or "spending a month on optimizations").
One java programmer writes an app that takes a rack of equipment to run and writes it in 6 months. Meanwhile, a C programmer takes 12 months and only 1/2 rack of machines.
After a year, the java app costs $40k in programming costs and an initial cost of $60k for hardware, so $100k. A year later, hosting costs rack up another $18k. The C app costs $80k in programming costs, $30k for hardware, so $110k. A year later, hosting costs rack up another $9k, so we're about even. You may argue that C takes > 2 times to write, and I will argue that java bloat requires more than a 2x hardware purchase, so we're talking pretty much a wash here. I don't think that your cost argument holds much water.
Moreover, going down the list of low hanging fruit in terms of reducing cost and rendering time per page-view the option to switch to a "more efficient" language is so far down the list that it's almost never reached. Indeed, it's often more important to switch to a language that makes it easier to scale out to more hardware than it is to switch to a language which is abstractly faster at individual optimizations (again, macro-optimization trumps micro-optimization). The biggest performance improvement efforts tend to be orthogonal to development language entirely. For example, tuning your database design and DB server parameters, using extensive caching, cutting down on http request overhead, etc.
It's telling that a company like facebook (which has no shortage of developer talent) chose to spend its efforts on making PHP faster by building a new compiler for it rather than moving away from PHP to some other hypothetically more efficient language.
Efficiency is an important factor in web development, it can affect end-user performance, costs, and profitability. But it's rarely as significant as many people make it out to be. It's more important to build something that people care about than it is to build something extremely efficient. For the vast majority of sites, increasing the popularity of your site by 10-100x is far more important than reducing the server footprint by 2x, or even 10x.
In most companies you don't have one programmer per rack but many programmers per rack. The hosting costs are usually dwarfed by the programmer salaries, often as much as to make the former appear as a rounding error.
Consequently you should in almost all cases optimize for developer-performance, not for software performance.
Sadly, it is the faults of java that pre-adapted it to success in a corporate environment; it creates an impression of vast complexity in even simple tasks and allows for large budgets and swollen headcounts that translate into more power for the leadership of projects in which it is used.