Global Warming and Java

Mile long iceberg

I’ve been losing the Java versus C++ argument for a long time.  Just look at the latest Tiobe Index. Even more disturbing are the languages in most demand in job listings.

Now I beg you for the sake of the planet, reconsider your use of Java for your next project.  Just consider how much electricity spent globally on computers.  Right now probably about 10% of the world’s energy goes to powering our computers (IT Electricity Use Worse than You Thought/). Some expect IT energy use to grow to 20% of mankind’s energy use by 2025.

One of the most bizarre arguments I’ve heard for the use of Java is that it is fast as C/C++.  If you consider half to a quarter as fast as C/C++ as the same, or fail to consider that you pay Java’s “Just-in-Time” compilation every time you run the application, then that argument is correct. Now consider what that slowness means.

(Look at https://benchmarksgame-team.pages.debian.net/benchmarksgame/which-programs-are-fast.html)

Some Numbers

(from https://en.wikipedia.org/wiki/World_energy_consumption)

10% of the world’s energy comes to about 15.75 petawatt-hours/year.  Your typical computer consumes about 120 watts.  An typical CPU takes about 85 watts, with the remainder consumed by memory, drives, and fans. In my calculations I’m not going to count the extra power needed to cool the machine because many machines merely vent their heat to the environment. 100% of the computer’s power consumption exhausts as heat. A computer converts no energy to mechanical energy.

According to the Tiobe index, Java powers 16% of the IT world. Let’s be generous and assume Java is only half as fast as C/C++, so that means 8% * 15.75 petawatt-hours/year = 1.2 petawatt-hours could have been saved per year. That’s about a 1,800 million metric tons of carbon dioxide.

What to do next

Despite the evidence, I doubt we can unite the world governments in banning Java. We can, though, wisely choose our next implementation language.

A long, long time ago, seemingly in a galaxy far, far way, I wrote my first program in Fortran 4 using punch cards.  Imagine my surprise when 40 years later a major company sought me out to help them with their new Fortran code.  They were still using Fortran because their simulations and analytics didn’t cost much to run in the cloud.  Besides being the language the engineers knew and love, it was less expensive by an order of magnitude in running it in comparison to other languages.

They had me convert much of the code to C/C++.  C/C++ was not as fast as the Fortran just because C/C++ allows the use of pointers and aliasing so the compiler can’t make the same assumptions as Fortran. Modern Fortran has a lot of new features to make it friendlier to engineers than the old Fortran 4, but frankly, it was a little like putting lipstick on pig. Object-orientation and extensible code is just a little difficult in Fortran.

Looking back at the benchmark game (previously mentioned https://benchmarksgame-team.pages.debian.net/benchmarksgame/which-programs-are-fast.html), some benchmarks actually ran faster written in C/C++ than in Fortran.  In fact, Fortran only ranked #5.

Looking at the C/C++ programs, though, many of them gained their speed through the use of inline assembly, so the benchmark game isn’t a fair measure. Looking at the #2 entry, though, Rust, shows something quite different.  The same applications written in Rust almost matched the C/C++ speed — but the Rust applications used no inline assembly, and were written in native Rust. The Rust applications looked elegant and clear, and at the time I didn’t even know Rust.

Every language teaches you a new way to solve problems.  Modern C++ is beginning to behave like Fortran in its accretion of features. You can use any programming paradigm in C++, and unfortunately programmers choose to do so, but you need to be a language lawyer to effectively write and use the features. In C++ it is easy to write not just unsafe code, but broken code.  For example:

char *imbroken(std::string astring) { return astring.data(); }

If you’re lucky your compiler will flag such monstrosities.

Rust, though, only allows you to “borrow” pointers, and you can’t pass them out of scope.  Rust forces you to account for every value a function returns.  Rust doesn’t have exceptions, but that’s intentional.  You must check every error return.  Take a look at it: https://www.rust-lang.org/

The new C++ is wonderful, but I’m losing my patience at intricate details.  I’m finding Rust frustrating, but I’m finding it re-assuring that if it compiles I’m miles ahead in having confidence that it is correct, secure, and fast. Someone even has a project to refactor the Linux kernel in Rust.