可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
As we could see from The Computer Language Benchmarks Game in 2010:
- Go is on average 10x slower than C
- Go is 3x slower than Java !?
How can this be, bearing in mind that Go compiler produces native code for execution?
Immature compilers for Go? Or there is some intrinsic problem with the Go language?
EDIT:
Most answers deny intrinsic slowness of Go languge, claiming the problem resides in immature compilers.
Therefore I've made some own tests to calculate Fibonacci numbers: Iterative algorithm runs in Go (freebsd,6g) with the same
speed as in C (with O3 option). The dull recursive one runs in Go 2 times
slower than in C (with -O3 option; with -O0 - the same). But I haven't seen 10x fall as in the Benchmarks Game.
回答1:
The 6g and 8g compilers are not particularly optimising, so the code they produce isn't particularly fast.
They're designed to run fast themselves and produce code that's OK (there is a bit of optimisation). gccgo
uses GCC's existing optimisation passes, and might provide a more pointful comparison with C, but gccgo isn't feature-complete yet.
Benchmark figures are almost entirely about quality of implementation. They don't have a huge amount to do with the language as such, except to the extent that the implementation spends runtime supporting language features that the benchmark doesn't really need. In most compiled languages a sufficiently clever compiler could in theory strip out what isn't needed, but there comes a point where you're rigging the demo, since very few real users of the language would write programs that didn't use that feature. Moving things out of the way without removing them entirely (e.g. predicting virtual call destinations in JIT-compiled Java) starts to get tricky.
FWIW, my own very trivial test with Go when I was taking a look at it (a loop of integer addition, basically), gccgo produced code towards the fast end of the range between gcc -O0
and gcc -O2
for equivalent C. Go isn't inherently slow, but the compilers don't do everything, yet. Hardly surprising for a language that's 10 minutes old.
回答2:
In the next release of the Go FAQ, something similar to the following should appear.
Performance
Why does Go perform badly on benchmark
X?
One of Go's design goals is to
approach the performance of C for
comparable programs, yet on some
benchmarks it does quite poorly,
including several in test/bench. The
slowest depend on libraries for which
versions of comparable performance are
not available in Go. For instance,
pidigits depends on a multi-precision
math package, and the C versions,
unlike Go's, use GMP (which is written
in optimized assembler). Benchmarks
that depend on regular expressions
(regex-dna, for instance) are
essentially comparing Go's stopgap
regexp package to mature, highly
optimized regular expression libraries
like PCRE.
Benchmark games are won by extensive
tuning and the Go versions of most of
the benchmarks need attention. If you
measure comparable C and Go programs
(reverse-complement is one example),
you'll see the two languages are much
closer in raw performance than this
suite would indicate.
Still, there is room for improvement.
The compilers are good but could be
better, many libraries need major
performance work, and the garbage
collector isn't fast enough yet (even
if it were, taking care not to
generate unnecessary garbage can have
a huge effect).
And here's some more details on The Computer Benchmarks Game from a recent mailing list thread.
Garbage collection and performance in gccgo (1)
Garbage collection and performance in gccgo (2)
It's important to note that the Computer Benchmarks Game is just a game. People with experience in performance measurement and capacity planning carefully match like with like over realistic and actual workloads; they don't play games.
回答3:
My answer isn't quite as technical as everyone else's, but I think it's still relevant.
I saw the same benchmarks on the Computer Benchmarks Game when I decided to start learning Go. But I honestly think all these synthetic benchmarks are pointless in terms of deciding whether Go is fast enough for you.
I had written a message server in Python using Tornado+TornadIO+ZMQ recently, and for my first Go project I decided to rewrite the server in Go. So far, having gotten the server to the same functionality as the Python version, my tests are showing me about 4.7x speed increase in the Go program. Mind you, I have only been coding in Go for maybe a week, and I have been coding in Python for over 5 years.
Go is only going to get faster as they continue to work on it, and I think really it comes down to how it performs in a real world application and not tiny little computational benchmarks. For me, Go apparently resulted in a more efficient program than what I could produce in Python. That is my take on the answer to this question.
回答4:
Despite the not so good efficiency of Go about the CPU cycles usage, the Go concurrency model is much faster than the thread model in Java, for instance, and can be comparable to C++ thread model.
Note that in the thread-ring benchmark, Go was 16x faster than Java. In the same scenario Go CSP was almost comparable to C++, but using 4x less memory.
The great power of Go language is its concurrency model, Communicating Sequential Processes, CSP, specified by Tony Hoare in 70's, being simple to implement and fit for highly concurrent needs.
回答5:
In the case of a couple of benchmarks, it's easy to point to the specific runtime or library differences that cause the slowdown.
The binary-trees benchmark is described as "an adaptation of a benchmark for testing GC." Go's GC is not currently where Java's or C#'s are, and on workloads with tons of pointer-containing objects and a lot of memory pressure it shows. If this were an issue in a live Go application, you'd implement your own object pool/free list to reuse objects of this one type [edit: the folks at CloudFlare, who use Go, just happened to post about how to do this]. That's an approach to controlling GC costs used in GC'd languages in general, but as the linked page notes it's excluded by the rules for this benchmark.
The pidigits benchmark uses Go's big-number-math library, which is slower than things like C's GMP or probably Java's libraries. If your application's performance is limited by bignum speed (may be a factor in public-key crypto and some math/sci apps; less of one in, say, Web app backends), you'd want to call out to the C library from Go or or just use a different language.
Many other differences likely come down to less-optimized code generation, as the accepted answer says.
You want to make your choices with a broader perspective than just benchmarks, of course. A lot of Go users, including me, seem to come from working with scripting languages, and seem to love the type inference, concurrency tools, and quick compilation. On the other hand, the relative immaturity of the ecosystem (compared to Java, C languages, or even Python) is a big downside, probably bigger than the benchmark numbers. Seems worth getting into if you have interest, in any case.
回答6:
Things have changed.
I think the current correct answer to your question is to contest the notion that go is slow. At the time of your inquiry your judgement was justified, but go has since gained a lot of ground in terms of performance. Now, it's still not as fast as C, but is no where near being 10x slower, in a general sense.
Computer language benchmarks game
At the time of this writing:
source secs KB gz cpu cpu load
reverse-complement
1.167x
Go 0.49 88,320 1278 0.84 30% 28% 98% 34%
C gcc 0.42 145,900 812 0.57 0% 26% 20% 100%
pidigits
1.21x
Go 2.10 8,084 603 2.10 0% 100% 1% 1%
C gcc 1.73 1,992 448 1.73 1% 100% 1% 0%
fasta
1.45x
Go 1.97 3,456 1344 5.76 76% 71% 74% 73%
C gcc 1.36 2,800 1993 5.26 96% 97% 100% 97%
regex-dna
1.64x
Go 3.89 369,380 1229 8.29 43% 53% 61% 82%
C gcc 2.43 339,000 2579 5.68 46% 70% 51% 72%
fannkuch-redux
1.72x
Go 15.59 952 900 62.08 100% 100% 100% 100%
C gcc 9.07 1,576 910 35.43 100% 99% 98% 94%
spectral-norm
2x
Go 3.96 2,412 548 15.73 99% 99% 100% 99%
C gcc 1.98 1,776 1139 7.87 99% 99% 100% 99%
n-body
2.27x
Go 21.73 952 1310 21.73 0% 100% 1% 2%
C gcc 9.56 1,000 1490 9.56 1% 100% 1% 1%
k-nucleotide
2.40x
Go 15.48 149,276 1582 54.68 88% 97% 90% 79%
C gcc 6.46 130,076 1500 17.06 51% 37% 89% 88%
mandelbrot
3.19x
Go 5.68 30,756 894 22.56 100% 100% 99% 99%
C gcc 1.78 29,792 911 7.03 100% 99% 99% 98%
Though, it does suffer brutally on the binary tree benchmark:
binary-trees
12.16x
Go 39.88 361,208 688 152.12 96% 95% 96% 96%
C gcc 3.28 156,780 906 10.12 91% 77% 59% 83%
回答7:
It all comes down to how long it takes to code something and how little work is necessary to get the best performance from whatever it is that is developed. Everything else is just a nerdy pursuit that doesn't have much relevance in business.......that sort of thing.
Go makes developing great services easier to support. Java...regardless of it's technical capability...nightmare to support....
I wrote some Golang programs....fast as shit through a goose......and if my task was to crunch serious mathematics all day long...I don't think I would use Java or Go for that...I would use a language designed for that sort of thing.
回答8:
There are two basic reasons that that Java is faster than Go and C++, and can be faster than C in many cases:
1) The JIT compiler. It can inline virtual function calls through multiple levels, even with OO classes, based on the runtime profile. This is not possible in a statically compiled language (although the newer re-compilation based on recorded profile can help). This is very important to most benchmarks that involve repetitive algorithms.
2) The GC. GC based memory allocation is nearly free, as compared to malloc. And the 'free' penalty can be amortized across the entire runtime - often skipped because the program terminates before all garbage needs to be collected.
There are hundreds (thousands?) of extremely talented developers making the GC/JVM efficient. Thinking you can "code better than all of them" is a folly. It is a human ego problem at its heart - humans have a hard time accepting that with proper training by talented humans, the computer is going to perform better than the humans that programmed it.
Btw, C++ can be as fast as C if you don't use and of the OO features, but then you are pretty close to just programming in C to begin with.
Most importantly, the "speed differences" in these tests are usually meaningless. The IO costs are orders of magnitude more than the performance differences, and so proper designs that minimize IO costs always win - even in a interpreted language. Very few systems are CPU bound.
As a final note, people refer to the "computer language benchmarks game" as a "scientific measure". The tests are completely flawed, For example, if you view the Java tests for nbody, it shows the CPU utilization at 30% for the Java program - which is impossible if the program does no IO. When I run the tests on the same OS/hardware, I get roughly 7.6 secs for Java, and 4.7 secs for C - which is reasonable - not the 4x slowness the tests reports. It is click-bait, fake news, designed to generate site traffic.
As a final, final note... I ran the tests using Go, and it was 7.9 secs. The fact that when you click on Go, it compares it to Java, and when you click on Java it compares it to C, should be a red flag to any serious engineer.
回答9:
I think an often overlooked fact is, that JIT compilation can be > static compilation especially for (runtime) late bound functions or methods. The hotspot JIT decides at RUNTIME which methods to inline, it even might adjust data layout to the cache size/architecture of the CPU it is currently running on.
C/C++ in general can make up (and overall will still perform better) by having direct access to the hardware. For Go things might look different as its more high-level compared to C, but currently lacks a runtime optimization system/compiler.
My gut tells me, Go could be faster then Java as Go does not enforce pointer chasing that much and encourages better data structure locality + requires less allocation.
回答10:
Both Java and C are more explicit with their data and method (function) definitions. C is statically typed, and Java is less so with its inheritance model. This means that the way the data will be handled is pretty much defined during the compilation.
Go is more implicit with its data and function definitions. The built in functions are more general in nature, and the lack of a type hierarchy (like Java or C++) gives Go a speed disadvantage.
Keep in mind that Google's goal for the Go language is to have an acceptable compromise between speed of execution and speed of coding. I think they are hitting a good sweet spot on their early attempt, and things will only improve as more work is done.
If you compare Go with more dynamically typed languages whose main advantage is speed of coding, you will see the execution speed advantage of Go. Go is 8 times faster than perl, and 6 times faster than Ruby 1.9 and Python 3 on those benchmarks you used.
Anyway the better question to ask is Go a good compromise in ease of programming versus speed of execution? My answer being yes and it should get better.