Programming

Go와 비교하여 왜 느린가 (Java와 비교)?

procodes 2020. 8. 3. 21:08
반응형

Go와 비교하여 왜 느린가 (Java와 비교)?


2010 년 컴퓨터 언어 벤치 마크 게임 에서 볼 수 있듯이 :

  • C 보다 평균 10 배 느리다
  • 자바 보다 3 배 느리다 !?

Go 컴파일러가 실행을위한 기본 코드를 생성한다는 점을 염두에두고 어떻게 이것이 가능합니까?
Go의 미성숙 한 컴파일러? 아니면 Go 언어에 본질적인 문제가 있습니까?

편집 :
대부분의 답변은 문제가 미숙 한 컴파일러에 있다고 주장하면서 Go languge의 본질적인 속도 저하를 거부합니다.
따라서 피보나치 수를 계산하기 위해 자체 테스트 수행 했습니다 . 반복 알고리즘은 sameC (O3 옵션 사용)와 같은 속도로 Go (freebsd, 6g)에서 실행됩니다 . 둔한 재귀 2 times는 C보다 느리게 실행됩니다 (-O3 옵션 사용, -O0 사용-동일). 그러나 나는 Benchmarks Game 에서처럼 10 배가 떨어지는 것을 보지 못했습니다.


6g 및 8g 컴파일러는 특별히 최적화되지 않았으므로 생성하는 코드가 빠르지 않습니다.

그들은 스스로 빠르게 실행되고 괜찮은 코드를 생성하도록 설계되었습니다 (최적화가 약간 있습니다). gccgo는 GCC의 기존 최적화 단계를 사용하며 C와보다 의미있는 비교를 제공 할 수 있지만 gccgo는 아직 기능이 완전하지 않습니다.

벤치 마크 수치는 거의 전적으로 구현 품질에 관한 것입니다. 구현에서 벤치 마크에 실제로 필요하지 않은 언어 기능을 지원하는 런타임을 제외하고는 언어와 관련이 없습니다. 대부분의 컴파일 된 언어에서 충분히 영리한 컴파일러는 이론적으로 필요하지 않은 것을 제거 할 수 있지만 데모를 조작 할 시점이 있습니다. 언어를 사용하는 실제 사용자는 거의 사용하지 않는 프로그램을 작성하기 때문입니다. . JIT 컴파일 Java에서 가상 호출 대상 예측과 같이 완전히 제거하지 않고 사물을 옮기는 것은 까다로워지기 시작합니다.

FWIW, Go를 사용한 매우 사소한 테스트 인 FWIW (기본적으로 정수 추가 루프)를 gccgo는 C gcc -O0gcc -O2동등한 C 범위의 빠른 끝으로 코드를 생성했습니다 .Go 는 본질적으로 느리지 않습니다. 그러나 컴파일러는 아직 모든 것을하지 않습니다. 10 분이 지난 언어는 그리 놀라운 일이 아닙니다.


Go FAQ 의 다음 릴리스에서는 다음 과 유사한 내용이 나타납니다.

공연

벤치 마크 X에서 Go의 성능이 왜 좋지 않습니까?

Go의 설계 목표 중 하나는 유사한 프로그램에 대해 C의 성능에 접근하는 것이지만 일부 벤치 마크에서는 테스트 / 벤치의 여러 벤치 마크를 포함하여 성능이 상당히 떨어집니다. 가장 느리게 작동하는 버전의 라이브러리는 Go에서 사용할 수없는 라이브러리에 따라 다릅니다. 예를 들어, pidigits는 다중 정밀도 수학 패키지에 의존하며 C 버전은 Go와 달리 GMP (최적화 된 어셈블러로 작성 됨)를 사용합니다. 정규식에 의존하는 벤치 마크 (예 : regex-dna)는 기본적으로 Go의 stopgap regexp 패키지를 PCRE와 같은 고도로 최적화 된 정규식 라이브러리와 비교합니다.

벤치 마크 게임은 광범위한 튜닝으로 승리하며 대부분의 벤치 마크의 Go 버전에주의가 필요합니다. 비슷한 C 및 Go 프로그램을 측정하면 (역상 보정이 한 예임) 두 언어가이 제품군이 나타내는 것보다 원시 성능이 훨씬 더 가깝다는 것을 알 수 있습니다.

여전히 개선의 여지가 있습니다. 컴파일러는 훌륭하지만 더 나을 수 있으며 많은 라이브러리에는 주요 성능 작업이 필요하며 가비지 수집기는 아직 충분히 빠르지 않습니다 (필요한 경우에도 불필요한 가비지를 생성하지 않도록주의하면 큰 영향을 줄 수 있음).

그리고 최근 메일 링리스트 스레드의 The Computer Benchmarks Game대한 자세한 내용 있습니다.

gccgo의 가비지 수집 및 성능 (1)

gccgo의 가비지 수집 및 성능 (2)

컴퓨터 벤치 마크 게임은 게임 일뿐입니다. 성능 측정 및 용량 계획에 경험이있는 사람들은 현실적이고 실제적인 워크로드와 같이 신중하게 일치합니다. 그들은 게임을하지 않습니다.


내 대답은 다른 사람만큼 기술적이지는 않지만 여전히 관련이 있다고 생각합니다. Go 학습을 시작하기로 결정했을 때 Computer Benchmarks Game에서 동일한 벤치 마크를 보았습니다. 그러나 솔직히이 모든 합성 벤치 마크는 Go가 당신에게 충분히 빠르지 여부를 결정하는 데 의미가 없다고 생각합니다.

최근에 Tornado + TornadIO + ZMQ를 사용하여 Python으로 메시지 서버를 작성했으며 첫 Go 프로젝트에서는 Go에서 서버를 다시 작성하기로 결정했습니다. 지금까지 서버를 Python 버전과 동일한 기능으로 가져 왔으므로 테스트 결과 Go 프로그램 속도가 약 4.7 배 증가했습니다. 나는 Go에서 일주일 동안 코딩을 해 왔으며 5 년 이상 Python으로 코딩 해 왔습니다.

Go는 계속해서 작업을 진행함에 따라 더 빨라질 것입니다. 실제로 컴퓨팅 벤치 마크가 아닌 실제 응용 프로그램에서 어떻게 수행되는지에 달려 있다고 생각합니다. 나에게 Go는 분명히 파이썬에서 생산할 수있는 것보다 더 효율적인 프로그램을 만들어 냈다. 이것이이 질문에 대한 답입니다.


여러가지가 바뀌었다.

귀하의 질문에 대한 현재 정답은 느리게 진행되는 개념에 이의를 제기하는 것입니다. 귀하의 문의 시점에 귀하의 판단은 정당화되었지만, 성능 측면에서 많은 근거를 얻었습니다. 이제는 여전히 C만큼 빠르지는 않지만 일반적인 의미에서 10 배 정도 느린 곳은 없습니다.

컴퓨터 언어 벤치 마크 게임

이 글을 쓰는 시점에서 :

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%

그러나 이진 트리 벤치 마크에서 잔인하게 고통받습니다.

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%

CPU 사이클 사용에 대한 Go의 효율성이 좋지는 않지만 Go 동시성 모델은 예를 들어 Java의 스레드 모델보다 훨씬 빠르며 C ++ 스레드 모델과 비교할 수 있습니다.

에 있습니다 스레드 링 벤치 마크 , 이동했다 16 배 빠른 자바보다. 같은 시나리오에서 Go CSP는 C ++과 거의 비슷하지만 4 배 적은 메모리를 사용합니다.

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.


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.


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. 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.

For a real world comparison of Java, Go, and C++ see https://www.biorxiv.org/content/10.1101/558056v1 spoiler alert, Java comes out on top in raw performance, with Go coming out on top with combined memory use and wall time.


As a matter of fact, Go is not only elegant and efficient at design time, but also super performant at run-time. The key is to use the right operating system i.e. LINUX. Performance profiling result under Windows and Mac OS are, for lack of a better word, one or two orders of magnitude inferior.


under linux, the go runtime is super fast, perfectly comparable with c/c++. the go runtime under windows and unix are not in the same league

comparison with java is not so important, go is for both system and application development (as java is more like blue collar for application development only). will not enter in details, but when things like kubernetes are written in go, you realize that is not an enterprise consultant friendly toy

i do not remember google mentioning even once about the compromise you refer to. go is well design, simple, elegant and efficient for for designing system and application level programs, has pointers, efficient memory allocation and deallocation, avoids complications arising from oh so easy to miss-use implementation inheritance, giving you co-routines and other modern ways to write high performance applications in time and budget. again, go is super fast under linux, which is exactly what it was designed for (very happy that it does)


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.

참고URL : https://stackoverflow.com/questions/2704417/why-is-go-so-slow-compared-to-java

반응형