Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

You can't really trust the computer language benchmark's game. Many of the solutions there have code that's as far from idiomatic as possible (nobody would write code like that in real production applications).

That said, two things:

1. Go is not particularly efficient as a language and its compiler doesn't optimize much compared to the other "efficient" language compilers (even the JIT ones).

2. These small benchmarks benefit JIT languages quite a bit since the JIT cost is barely noticeable. In large real-world apps constantly running a compiler in the back is not exactly efficient. It'll pay for itself vs interpreted languages, but never against AOT compiled ones.



> Go is not particularly efficient as a language and its compiler doesn't optimize much compared to the other "efficient" language compilers (even the JIT ones).

I mean, relative to many other mainstream languages including many of the JIT languages, Go is very efficient, but a lot of that efficiency comes from the language design (e.g., idiomatic value types) such that the compiler and runtime don’t need to be as smart.

Agreed that the benchmarks game is a pretty crumby measure of performance, but it typically imposes strange restrictions on Go that prevents it from showing its idiomatic performance (never mind its ceiling). For example, languages with garbage collectors aren’t allowed to preallocate memory for certain benchmarks even though that’s absolutely idiomatic in Go (because Go has value types) so you have languages with GCs optimized for languages where everything is an allocation which perform well and languages like C and Rust which are allowed to preallocate because they don’t have a GC (which is a weird criteria) and then you have Go which appears to be very slow because it’s forced to allocate in a tight loop.


Yes Go's design is not bad as far as efficiency goes, but it's not amazing either.

From a language design perspective (when it comes to "ease of optimization") it's much better than Java and comparable to C#.

But compiling C# with CoreRT (which is basically .NET Core's RyuJIT configured as an AOT compiler) shows just how little Go's compiler optimizes. Go would need to be even more "easy to optimize" than it is to make up the difference. Rust and C++ are both easier to optimize and their compilers are in a whole other league entirely, and it shows on the horrific compilation speeds.

I'm not sure what the right way to do these "benchmarks" is. Some of the code I've seen there was more low level and convoluted than stuff I'd write in C. Not even remotely representative of how the languages are used. Stupid rules like that one you mentioned also don't help since some languages get to preallocate and others don't.


Agreed--Go isn't in the top tier of languages with respect to efficiency--the languages in this tier trade off a lot of other facets to get high performance, and those tradeoffs don't align well with Go's goals. That said, I would be curious what sorts of optimizations Go could add which would pay for themselves with respect to keeping compile times fast. I don't know a lot about compiler optimizations, but I find the topic very interesting at least as it pertains to languages I use (I really don't care much about Haskell or OCaml or any of the other PLT darlings).


> I'm not sure what the right way to do these…

In which case, maybe what you see is as good as you'll get.

> … some languages get to preallocate…

Here's Go using a library pool —

https://benchmarksgame-team.pages.debian.net/benchmarksgame/...


The sync library is part of Go's standard library and is meant to allow safe concurrent access by multiple goroutines. It's pretty idiomatic Go!


Yes — so "allowed to preallocate memory" ?


> … aren’t allowed to preallocate memory…

Because as-you-know the whole point is to "allocate zillions of short-lived nodes" —

https://news.ycombinator.com/item?id=29323468


The C++ and Swift implementations use a node pool from the Apache Portable Runtime. This benchmark would be a lot more interesting if we got to see the price of C++'s RAII or Swift's reference counting.

The Swift Code looks like something you'd write in C.


> … the price of C++'s RAII…

Like this? (There are 8 other C++ binary trees programs.)

https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

> … or Swift's reference counting.

Like this? (There are 4 other Swift binary trees programs.)

https://benchmarksgame-team.pages.debian.net/benchmarksgame/...


You could ask the authors to update their study.

You could look at the different binary trees programs shown on the current benchmarks game.


“It’s not a bad benchmark, it’s just showcasing a contrived scenario with different sets of rules for different kinds of languages”.

Most people aren't building applications whose business requirements preclude preallocating memory except for languages which lack garbage collectors.


So those are scare quotes not actually quotation?

If we don't experience a performance problem, we don't need a workaround.


No, that’s not an actual quotation. I was having a laugh at the silly logic which attempts to justify the benchmark. And preallocating isn’t a workaround, it’s idiomatic in Go.


That is not a contradiction: it can be both idiomatic in Go and a workaround to avoid garbage collection.


And that’s a valid point for the set of applications whose purpose is generating garbage. But overwhelmingly this isn’t interesting and people mistake this benchmark for a useful indicator of programming language performance in the general case.


And the set of applications that will inevitably generate garbage, which might be left to automatic garbage collection.

Errare humanum est.

"Energy Efficiency across Programming Languages" not "programming language performance in the general case".


It’s not a very compelling defense of a benchmark to argue that it measures something different for some languages than others—in this case for Go the benchmark measures poorly/carelessly written code while for other languages it measures meticulously optimized code.

I maintain a contrived benchmark is not a useful benchmark.


In this case for Go, the same as other languages that provide automatic garbage collection.

In this case for Go, the same as other languages that provide a library pool implementation.

Apparently the study authors found a use.


> Many of the solutions there…

You are looking in the wrong place.

Here are the 4 year old programs used in the "Energy Efficiency across Programming Languages" study —

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

> … nobody would write code like that…

When you tell us you wouldn't, we should all believe you.

When you tell us nobody would, we should ask how you know.


> You are looking in the wrong place.

Well, I randomly went and opened the C# binary tree example. I see a TreeNode struct with a private Next class inside of it. Can't think of any reason to write a BinaryTree like that in C# beyond trying to game some benchmarks.

The C++ implementation uses a node pool from the Apache Portable Runtime (a C library). Also not idiomatic (how did they get away with using a library?!). I particularly love how it doesn't even use std::string to write text to.

The Swift implementation also uses the Apache Portable Runtime node pool, completely non-idiomatic (even less justifiable than the C++ one), don't need to go into detail on this one.

The Go and Java implementations look perfectly normal for the respective languages. The Dart one too, but that one doesn't even use any concurrency so it's starting from a losing position.

This is not a fair comparison.


> … beyond trying to game some benchmarks…

Did it work?

If it wasn't massively more performant than other ways to write that program in C#, then maybe it's just fine for the purposes of "Energy Efficiency across Programming Languages".

> … but that one doesn't even use any concurrency…

What is the relationship between multicore and energy efficiency?

> This is not a fair comparison.

The comparison is energy efficiency not elapsed seconds, yes?


Comparing the energy efficiency of code that's not even doing the same thing is not a useful comparison. If you're running these benchmarks on a server that's always running full throttle then using more cores will use less power because the software finishes faster. If you're running on a laptop the relationship between core usage, elapsed seconds, and power usage is very non-linear.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: