85 comments

[ 3.3 ms ] story [ 151 ms ] thread
But is green worth paying the insecurity price? You could extend such interesting comparative paradoxes to other language comparisons as well, which I always find interesting.
If HFT businesses just don't bother using safe language then probably there is something in these languages.
"Why we chose Java for our High-Frequency Trading application"

https://medium.com/@jadsarmo/why-we-chose-java-for-our-high-...

Some random job ads picks,

"Senior Low Latency Java Developer" at Barclays

https://uk.indeed.com/viewjob?jk=41b8fb53bd4e24f8&tk=1hl2ggf...

"Senior Rust Developer" at James Joseph Associates

https://uk.indeed.com/viewjob?jk=c2865fa5668cf524&tk=1hl2ggf...

"Software Engineer Java Rust eTrading" for an hedge fund

https://uk.indeed.com/viewjob?jk=9c75cefc6a46276c&tk=1hl2ggf...

https://old.reddit.com/r/rust/comments/bhtuah/production_dep...

"Because Rust" and safety, of course. I wonder if programming on Windows just sucks in general, and all these are Windows trading shops. Do you even have all the tools you need to write large programs on Windows? Valgrind, libfuzzer, etc. etc.

Plenty of tools, assuming one doesn't come to Windows with an UNIX mindset, or wants freeloading.

Now those folks have a home in WSL.

I'm my personal (and biased) experience, C++ is significantly more common than Java in HFT (which does exist, along some C#). I'm not aware on anybody doing pure C although I'm sure there are.
(comment deleted)
What is the difference between using static variable and placing something via alloca? And I am surprised how badly Rust beats C++ it should not be possible imo.
It really shouldn't. Rust has internal sanity checks where C/C++ doesn't. C++ also has better abstractions often leading to better whole-program performance than C. In C you would have to obsess about each little thing to keep up. It's a red flag for the whole article.
The sanity checks don't add up to much with speculation etc. Since the Rust compiler has more information about memory management it can optimize some things a c++ compiler can't.

Also, you can write unsafe rust just like c++ and preallocate pools of memory and stuff etc

One of the strengths of C++ is just that, that the more information you can provide, the better opportunities for optimizations. If you're saying that Rust adds more information than C++, then sure, it would be possible for it to optimize better. But is that the case right now?
Yes, for example Rust has significantly more detailed aliasing information than C++, since Rust has the borrow checker while C++ has to get by with weird type-based heuristics (and doesn't even have a way to override that in the standard, though most compilers allow restrict in C++ mode as an extension)
The borrow checker gives the compiler significantly more information about memory. The rust compiler exposed some bugs in LLVM because LLVM tried to use this extra information, but because it could never do so for cpp the code was buggy.
Here are just a couple of examples related to having better information:

1. Take one of those most popular basic types provided by the C++ stdlib, std::vector<T> a growable array type and compare the analogous Rust type Vec<T>

std::vector<T> has a reserve method, but it's actually not equivalent to Vec::reserve instead it's equivalent to Vec::reserve_exact and there is no analogue for Vec::reserve provided, as a result without re-implementing the amortized exponential growth trick yourself you can't achieve similar performance benefits. The reserve vs reserve_exact distinction allows programmers who know something to help the type perform well.

2. The Guaranteed Niche Optimization. If Rust's compiler can see why type T doesn't need all possible bit patterns for its memory layout, then Rust guarantees that sum types consisting of a single value plus type T are optimised to the same size as T. C++ can approximate this using specialization for library types such as std::optional (but it typically doesn't) however it cannot provide the guarantee and in practice doesn't deliver the resulting performance.

Rust's &T has such a niche (the "null" pointer value), so do (Unix) OwnedFd and (Windows) OwnedSocket and the non-zero integers like NonZeroU32. Thus all of these types have the guaranteed optimisation when used in your own types and such sum types can be used exactly like "sentinel" values in C except that they're type safe so you'll write fewer bugs.

There are a lot of these leaks in the C++ language and standard library, and they add up. If you want to counteract them your C++ development gets slower and more expensive which wasn't a problem when there was no alternative, but now there is.

Looking at the benchmark where C++ is worst compared to other languages, it's depending on the library used. I would guess if they used Google's re2 Regex library instead of Boost's, the result would be different.

https://github.com/google/re2

https://github.com/greensoftwarelab/Energy-Languages/blob/ma...

What about Assembly?
It's easy to imagine that assembly code that's written with readability and maintainability in mind is less efficient than a readable and maintainable C program compiled with optimizations. But in any case, the difference between any compiled language and assembly is much smaller than any interpreted language and any compiled language.
Given that system failures have a significant cost associated with them, because people are the no.1 consumer of energy when idling around (still gonna consume wether trains go or not), there is a really good point to be made that the 5% overhead that rust adds is totally worth it.

Better software is also good against obsolescence, I feel like one of the reasons my Sonos experience has degraded over the years is because they realised that their initial product was too good, and people weren't upgrading ever.

(2021) - rehashing a paper published in 2017...

I think I still remember the discussion from back then, and it centered (as usual) around doubts if samples from Computer Language Benchmarks Game are really representative, and if some of the differences aren't due to the different levels of polish that the solutions in some languages have vs. others.

Why would you think the Benchmarks game is relevant in any way?
Why would you think measurements of a tiny tiny number of tiny tiny programs have something definitive to say about the immense variety of software in-use?
Computers are simple machines. The simpler your output assembly is, your code will be faster. The less safeguards your language or compiler forces on your output assembly, your code will be again faster.

C has the least number of safeguards, and most foot-guns by default, unless you opt-in to more. Same is for C++.

There are very legitimate reasons where you don't want bound checking in your arrays in some applications, and you can realize these in C and go really fast if you need to.

Tangentially, FORTRAN is a "FORmula TRANslator", so it's good and fast at math too. Because it is designed to do that. If you think FORTRAN and C are obsolete. Come to HPC domain, where you push languages and hardware to the limits without leaking memory and crashing randomly.

What could possibly be "really representative" of the immense variety of software in-use?
(as a PHP web developer...)

This is interesting, though of course it's only a partial picture: it doesn't talk about database optimisation or caching, and most of web development efficiencies for large sites are from things improving your table indexes, caching or periodically generating frequently consulted output etc.

Also (personal opinion) I think people often over-engineer projects which might sit comfortably on a single box, and of course that contributes to overall energy use.

Finally, this is all for the birds if everyone remains obsessed with mining crypto, training AI models and watching videos when reading a bit of text would do.

The research does not match the title. C is performant/energy efficient, but C isn't a very green choice for an average project because you require more programmers who cost a ton of money and are likely to spend it on flight trips, SUVs et cetera.
You cannot just look at the cost and energy expenditure of running the program, you should also look at the development, which is a lot more expensive for C. And more importantly you should look at the opportunity cost of the programs not being written and improving the world due to the use of a less productive language.
Programs are run more often than they are written.

So while I agree that it should be considered. Please remember that the weight can be totally different depending on if it's a one-off program, a small utility that's intended for a population of 100 people- or if it's curl.

Yes, but the small utility is used to save time, and thus energy. If it is not written because it is too expensive / complex to do it in C, then people will continue to waste energy. It is better to have the utility even if it is not perfectly implemented than not having it
That is indeed my point.
Let's take a simulation code, where accuracy and precision is important, and is achievable in both C and Y (a hypothetical, more productive language).

Let's say you spent a couple of months less time in Y to get the same program, but your hot core loop, which handles the iterations, runs 1-2 seconds slower in general. Let's say this loop takes 30 seconds in C, and 32 seconds in Y. You need 4000 calls of this function for a single solve.

You lost 8000 seconds per solve. 2.2 hours. In every ~650 runs, you lose these two months of time you saved in development. 650 runs is a lot of runs you think. No it's not. It's a single run, fired in parallel on a 1/3rd of a 2000 node cluster, which is small in supercomputing world. These two seconds saves me 2 hours on a single run. Which means I mean I save a day in 12 runs. This means, I can run at least 650 more test cases on the same cluster.

This snowballs as the research moves forward.

Losing a couple months in C or FORTRAN doesn't mean much in a multi-year research project. You reap the speed benefits measured in CPU-years.

This is why we still love C/C++/FORTRAN. Because they're more productive in the end.

But in the couple of months you didn't have your better weather simulation, the rest of the world was working less efficiently because your better data was not available. This might (or might not) offset your simulation efficiency.
Long tail of science doesn't iterate like a startup. 48hrs to PoC, 2 months to product, 24 months to exit is not something you do.

Bleeding edge science rarely works at break-neck competition. When you're competing you can iterate programs while your research is ongoing, so these two seconds doesn't lose its value either.

Even if you start to churn late, you finish early, because it's like an ion drive. Small, yet constant acceleration brings you great speed on the long run. These projects generally run for years, too.

By that argument, we should spend an arbitrary amount of time writing everything in very efficient assembler code, as long as we will ... after years and years of coding ... run the code often enough.

It's not only about the number of answers in $timeframe, it's also about timeliness of the first answer.

In reality, a well optimized C code with a good compiler can really reach to the practical limits of an hardware platform.

On another side note, as I noted earlier, science doesn't work like this for most of the time, unless we're going something like COVID-19. Even in these cases, you already have a good enough software base to begin with. So you iterate upon the better one while you bang the living life out of your existing solutions.

I just want to note, that reliability becomes an issue at scale as well. C can be the first to crash making it's "faster speed" useless. An example: there was a benchmark game for DNA GC counting. C was the fastest at beginning (a vectorized rust version has taken over). However, the C version in the lead at that time was the only version that could not count the GC ratio in human Chromosome X. Due to segfault/integer overflow. So in practical terms the C version was really infinitely slow even if the top ranker in the benchmark.

On a person note: I am dealing with C segfault ruining 261 hours of compute, which will probably need about a 1000 or so more to debug :(

Then I can say that the C version for that game was designed badly from the start. You should not do that kind of mistakes when laying your foundation down.

I understand your pain. I have written a material simulator in C++ which didn't use any safety barriers after the startup process, which made sure that it was safe to start the hot loop. On the other hand, my code never had a memory leak or never crashed, because I knew what I was going into and designed it appropriately. Most importantly, that thing is fast. Millions of iterations per core per second fast.

C _is_ the most productive language for certain tasks!
I'm very surprised they don't even mention the efficiency of the developer in this context - C might be the greener language once the system is developed, but it's somewhat common sense that a higher-level language should significantly lessen development time.

Since developers needs to run an entire OS incl. employer/administrative overhead for the time they're developing, the greenest thing one could do for software is improving DevEx. (at all levels - language, infrastructure, tooling)

I'm talking about the majority of software being developed here - if you're FAANG or run a system with huge loads then the trade-off might be worth it.

Development time makes up a nearly immeasurable fraction of power resources outside of the tiniest teams.
Imagine you have a team migrating the federal tax system of a smaller country - you can choose to develop the project in C and have X amount of devs work on it for 3-4 years 40-50h a week. The resulting code base will be huge and probably hard to maintain.

Or you could choose to hire devs in a higher level language, maybe X/2 or X/1.5 amount of devs - saving you the environmental cost of running possibly hundreds of workstations every single day for years at a time and doing administration for more employees. The resulting code base will also be smaller and (hopefully) easier to maintain.

I don't think you could call this immeasurable at all. (This is based on a real example)

Not just the workstations. You really need to factor in the other carbon output of those developers for the time spent on the project too, not just the tools.

And you then need to consider to what extent any performance saving will be efficiently captured as reduced power use.

But, yes, fully agree.

One system I worked on recently involved about 20 developer years of effort, and about 40 core years of computation... I'm pretty sure the developers machines combined spent far more energy than the production systems, for a Ruby deployment, before factoring in any other energy use relating to difference in effort.

IME development resources will always expand to the available budget and time anyway, the programming language or programmer skills really don't matter much.

Also, whether C is actually more or less "productive" than other languages for specific tasks isn't all that clear either. For the things I pick C for (for instance cross-platform libraries sitting between OS APIs and user code, and home computer emulators), it is also the most productive option (in the sense that higher level programming languages wouldn't make me more productive, because all that's needed for this type of stuff is functions, structs, loops, conditionals and a handful of math operators - and all those things are in C). High level features like automatic memory management don't make much sense when there's hardly any heap memory to be managed, and a rich stdlib also isn't needed when all you do is number crunching and bit twiddling.

And you need to keep this in account when considering efficiencies in general.

My first production Ruby project increased our CPU usage in userspace tenfold for the service where it replaced a C version. At a point where it processed millions of messages a day, that added up to 10% of one core.

The carbon cost of the development effort almost certainly outweighed the cost of running the service - either version - by a large factor, and hence any savings on dev effort might easily (might, as I didn't keep precise records) have outweighed production costs by a significant factor too. The Ruby version was less than 1/10th the size despite more features.

So I agree with you. Many systems have plenty of services like that. Some systems are very clearly not like that and are worth optimizing, as you say.

Is looking at current running costs the only metric?

Computer co2 emissions are dominated by manufacture, not use.

At some point the extra bloat means you have to upgrade your computer / buy another one.

The point is that for a lot of services that "at some point" never come, and/or favors avoiding "extra bloat" in the development team rather than production servers.

By all means, assess the costs and benefits - I've done projects where I've optimized heavily for performance because it means we could shave tiny amounts of power use off embedded systems we hoped to deploy in large quantities; I'd certainly not deploy Ruby there.

But people seem to have a tendency to overestimate the scale they will need, often dramatically, and often because they have no idea the size of their total addressable market or the amount of data available in a given space (e.g. I've seen developers worry about scaling things to large clusters in niches where actually talking it through with a business analyst would've made them realize that a total saturation of the product to 100% of the maximally possible worldwide market for their service would see it all fit on their laptop)

Unless you actually sit down and work out what your realistic scaling scenarios look like, you don't know whether a tradeoff of time vs. performance will ever pay off.

Even when you do need a scale where putting significant effort into performance matters, there are many scenarios where starting "inefficient" is still more efficient, because it lets you focus more effort on the parts of the system that are proven in real-world settings to actually carry a cost that matters, and the most cost-effective solutions might well be different than what you expect.

E.g. one other aspect of the system that included the Ruby component I mentioned actually hit scaling challenges. Instead of investing time in rewriting it, we cut the computational cost to fractions of a percent by just caching the main pages for a few seconds (I want to say 10, but not sure the exact number). The total energy use for generating those pages once that cache was in place (reconfiguring the reverse proxy that was already in place) was so low that rewriting that part in a more efficient language would equally have saved at most fractions of a core.

Instead of spending extra dev time on that, we got to spend the extra dev resources where it did matter, such as e.g. the backend search engine indexing and query engine, where processing costs certainly would have killed us if it'd been written in a slow language.

Basically, know your costs.

Your fully loaded, real costs, including the actual dev costs by service and by feature. Developers in particular tend to have absolutely no clue about the fully loaded costs of the choices they make, and it often shows in the choices they make.

EDIT: I'd like to add that this is often not the fault of developers. It took years, and very specific circumstances (co-founding startups, that exposed me much more to the money side) before I started seriously thinking about the costs of what I built, and sitting down and actually calculating "worst case" scale and likely scale, and estimating costs of going from one to the other if we engineered for the smaller scale. It's not a habit most developers have, because it's not something most developers get asked, even though they ought to at the very least be involved (a lot of the time I've seen costing done by architects, or even worse directors or VPs with no exposure to the hands on work, it bears little resemblance to reality).

> The carbon cost of the development effort almost certainly outweighed the cost of running the service

I don't imagine you were going to put yourself into low power mode as the alternative to development time

No, but you'd be doing other things. Not allocating the effects of tying up people towards the energy cost of providing a service creates perverse incentives.
> I'm very surprised they don't even mention the efficiency of the developer in this context

Because in terms of energy use it doesn't matter. Take any somewhat successful video game for example. It might take years and hundreds of developers to create, but all the energy used during that period is most likely just a fraction of running the game hundreds of thousands of times on the first day after release.

This is a very specific example since video games genuinely require loads of resources to run at the end user side. Most software projects aren't client-side behemoths like that.
Ok, then web browsers :) Run by many more people than video games, but (not quite as) heavy when it comes to resource usage.
How many people do you know who work on browsers though?
A handful, but there are definitely more people who *use* browsers each day than there are people developing browsers. That's the whole point of the argument ;)
As I said, if you are FAANG or similar - which browsers are - the trade-off might be worth it, yes. But only a handful of software projects out there are browsers or video games.

That's the whole point of the argument. ;)

The development time is almost inconsequential. Software is written once-ish, read a few times, and run many, many times.
You also have to factor in how urgently you need the software.
I don't agree with this, developers will just develop something else with the extra time, their footprint is a constant.
The greenest programming language is no programming language. Maybe we don't need to build so many new apps.
The user facing apps are the tip of the iceberg in computing. The really power consuming stuff is not on your phone or computer most of the time.
That would actually be an interesting comparison (and I guess the answer isn't at all obvious): is there more computing power decentralized in billions of mobile phones, computers and game consoles (even washing machines), or centralized in thousands of data centers?
According to Wikipedia, Google's datacenters use a total of 500MW globally (which is very efficient to be honest). On the other hand, a standard Top10 supercomputer uses around 5MW (a ballpark figure), Assuming that Amazon also uses that amount of power, We're looking at 1250MW of power used by top computing centers around the world. This number is probably higher as we add cloudflare, OVH, and other countless data centers. Bitcoin is not added because, well, we're talking computing.

I think ~5W is a good approximation for mean power draw of smartphones. I don't know the duty cycle approximation, so I'll assume that number is 2.5W with 50% duty cycle.

This boils down to 500 million smartphones, approximately.

Of you think in terms of gaming PCs and consoles, 400W is a good approximation of the fleet. Again, if we think 50% duty cycle (at 200W), we have 1.562.500 PCs.

So I think, the data centers spend the same amount of power as the rest of the infrastructure, at best. Again, a bigger sample will again tilt the power towards data centers, I assume.

(comment deleted)
It also costs much more human lives.
This actually needs citation.

All your computing devices run massive amounts of C code, yet we don't hear much about people dropping dead in front of their computers, killed by a memory corruption issue?

In the only really popular case where a medical device killed people because of software bugs (Therac-25), the programming language was PDP-11 assembly. But even then the fault was much more in the software development process than the programming language.

I'm just saying coding in C costs significant more human hours, literally.
That also depends on the task at hand. Text processing in C with just the stdlib? Sure, waste of time. Number crunching via SIMD intrinsics? The best option for that is most likely C with compiler-specific extensions.
Any programming language can have SIMD extensions, and in fact a couple of them do, nothing special about C in that regard.

If anything it has been a pity that it didn't happen sooner, right away as SIMD became common.

It has to be, since it's been around since 1970s.
This is a repost of a low quality paper from 2017 [1]. It's low quality because they haven't done anything truly novel - they simply took the results of the benchmarks game [2] and flipped it. The ones that ran faster are considered greener.

But there are so many other factors to consider. For example, if a language uses all available cores on the machine it's running on, that's a more efficient use of resources than ones that run single threaded by default. Unless of course, your deployment configuration has multiple processes scheduled so no cores are wasted (but assuming they're not bottlenecked by memory). But once we start discussing specifics like how individual deployments happen we can no longer make blanket statements about an entire language.

All that assuming the benchmarks game tells you something reasonable about how real world programs look. They're hyperoptimized by hand with inline assembly, barely readable. That's not normal.

The other issue is that real world programs are large, with dependencies that we pull in. Benchmarks game programs are relatively small and in a single file, no dependencies. Is that what the average Python, Javascript or Rust program looks like in production? What are we even comparing at this point?

They chose to use benchmarks game because it already existed and required minimal effort from them. I'm reminded of the alcoholic using a lamppost - more for support than illumination.

[1] - https://greenlab.di.uminho.pt/wp-content/uploads/2017/10/sle...

[2] - https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

The basic idea makes a lot of sense though when there's tons of server-side code running in interpreted PHP, Python or JIT'ted Javascript which would run 10x .. 100x faster and more energy efficient when picking any compiled language instead.

Interpreting and JIT'ing wastes a lot of resources with identical but unnecessary work on each invocation that would only need to happen once before deployment. We're not recompiling C++, Swift or Rust applications each time they are started on the user's mobile phone either.

It's certainly possible to make the case you're saying. And I would be interested in reading such a paper. But my view is that someone using the benchmarks game hasn't proved anything.
> How often do you restart the server so that the JIT compiling time matters?

In a highly dynamic language like Javascript you have not much control on when which parts of the code might be 'de-optimized' and re-jitted (e.g. when the 'shape' of objects changes), it definitely doesn't only happen at startup or when a function is first called.

How often do you restart the server so that the JIT compiling time matters? (Moreover the result is often cached.)

This point it's more relevant for full interpreters... And perhaps better compilers matter more than their performance - it just so happens that C and C++ compilers are the most developed at the moment. (Except perhaps some shader compilers and Fortran.)

The JIT cost gets more egregious in JavaScript since it's paid by every user. Wasm is therefore much more efficient if we can skip the JS compiler...

> For example, if a language uses all available cores on the machine it's running on, that's a more efficient use of resources

I don't see how that's true. From an efficiency point of view, I think that what matter is resource usage per work done.

Are you considering the resources it took to create the chip itself? If you’re running a single threaded process on a multi core machine and nothing else, the rest of the processor is being wasted.

Further, the way modern processors conserve power is by the “race to sleep”. If it can complete the task quickly, the processor enters a lower power sleep mode. Therefore a language that allows us to easily write multithreaded code will reach this state quicker and consume less power. It’ll be “greener”.

Surely part of conserving resources is matching your hardware to the load. In the same way you wouldn't reserve a datacenter for a job that can be done on a single machine, you wouldn't reserve a large machine for a single-threaded load. You either pick a smaller, more efficient machine or do more work on that machine.

Also if you are single threaded you do not have to race to sleep on all the other cores. They are already sleeping.

> they simply took the results of the benchmarks game

No, they selected some of the programs and made their own measurements.

> The ones that ran faster are considered greener.

No, they used Intel’s Running Average Power Limit (RAPL) to measure energy consumption.

This is an old paper, and there was an updated version not even mentioned.

Anyway, the "greenest" programming language is most likely the one that successfully distract us from reproducing [1], or from using Bitcoins [2].

[1] https://iopscience.iop.org/article/10.1088/1748-9326/aa7541

[2] https://doi.org/10.1016%2Fj.joule.2022.02.005