C Is the Greenest Programming Language
hackaday.com
hackaday.com
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.
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)
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.
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.
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.
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.
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).
I don't imagine you were going to put yourself into low power mode as the alternative to development time
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.
That's the whole point of the argument. ;)
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/...
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.
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.
Other comments you've made on this topic seem wrong on basic facts?
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...
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.
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”.
Also if you are single threaded you do not have to race to sleep on all the other cores. They are already sleeping.
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 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.
C Is the Greenest Programming Language (33 comments) 2 years ago: https://news.ycombinator.com/item?id=29263961
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
https://www.sciencedirect.com/science/article/abs/pii/S01676...
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.
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.
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.
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.
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.
It's not only about the number of answers in $timeframe, it's also about timeliness of the first answer.
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.
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 :(
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.
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.
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...
"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.
Now those folks have a home in WSL.
Also, you can write unsafe rust just like c++ and preallocate pools of memory and stuff etc
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.
https://github.com/greensoftwarelab/Energy-Languages/blob/ma...
re2 https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
boost https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
regex-redux https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Energy Efficiency across Programming Languages (2017) [pdf]
A year ago:
https://news.ycombinator.com/item?id=32920990
3 years ago
https://news.ycombinator.com/item?id=24642134
6 years ago
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.
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.
If anything it has been a pity that it didn't happen sooner, right away as SIMD became common.