문제

제가 이해한 바에 따르면 C/C++는 특정 컴퓨터 아키텍처에서 실행되는 기본 코드를 생성합니다.반대로 Java 및 C#과 같은 언어는 기본 아키텍처를 추상화하는 가상 머신 위에서 실행됩니다.논리적으로 보면 이 중간 단계로 인해 Java나 C#이 C++의 속도를 따라잡는 것은 불가능해 보이지만 최신 컴파일러("핫스팟")는 이 속도에 도달하거나 심지어 이를 초과할 수도 있다고 들었습니다.

아마도 이것은 언어 질문이라기보다는 컴파일러 질문에 더 가깝지만, 이러한 가상 머신 언어 중 하나가 모국어보다 더 나은 성능을 발휘할 수 있는 방법을 일반 영어로 설명할 수 있는 사람이 있습니까?

도움이 되었습니까?

해결책

일반적으로 C#과 Java는 IL이 처음 실행될 때 컴파일하는 컴파일러인 JIT 컴파일러가 컴퓨터에 쿼리할 수 있기 때문에 C++ 컴파일된 프로그램이 할 수 없는 최적화를 수행할 수 있기 때문에 그만큼 빠르거나 더 빠를 수 있습니다.시스템이 Intel인지 AMD인지 확인할 수 있습니다.펜티엄 4, 코어 솔로 또는 코어 듀오;또는 SSE4 등을 지원하는 경우

C++ 프로그램은 일반적으로 혼합 최적화를 사용하여 미리 컴파일해야 모든 컴퓨터에서 제대로 실행되지만 단일 구성에 비해 최적화되지는 않습니다(예:프로세서, 명령어 세트, 기타 하드웨어).

또한 특정 언어 기능을 통해 C# 및 Java의 컴파일러는 C/C++ 컴파일러가 수행하는 데 안전하지 않은 특정 부분을 최적화할 수 있는 코드에 대한 가정을 할 수 있습니다.포인터에 액세스할 때 안전하지 않은 최적화가 많이 있습니다.

또한 Java 및 C#은 가비지 수집기와 코드 사이의 추상화 계층을 통해 모든 힙 압축을 한 번에 수행할 수 있으므로(상당히 비용이 많이 드는 작업) C++보다 힙 할당을 더 효율적으로 수행할 수 있습니다.

이제 다음 항목에 대해서는 Java에 대해 말할 수 없지만 예를 들어 C#에서는 메서드 본문이 비어 있음을 알 때 실제로 메서드와 메서드 호출을 제거한다는 것을 알고 있습니다.그리고 코드 전반에 걸쳐 이러한 종류의 논리를 사용합니다.

보시다시피 특정 C# 또는 Java 구현이 더 빠른 데에는 많은 이유가 있습니다.

이제 C++에서는 C#으로 할 수 있는 모든 작업, 특히 그래픽 영역과 하드웨어에 가까운 모든 작업을 날려버릴 특정 최적화가 가능합니다.포인터는 여기서 놀라운 일을 합니다.

그래서 당신이 쓰는 내용에 따라 나는 둘 중 하나를 선택할 것입니다.그러나 하드웨어에 의존하지 않는 것(드라이버, 비디오 게임 등)을 작성하는 경우 C#의 성능에 대해 걱정하지 않을 것입니다(Java에 대해서는 말할 수 없습니다).괜찮을 거예요.

하나는 Java 측, @스와티 좋은 기사를 지적합니다.

https://www.ibm.com/developerworks/library/j-jtp09275

다른 팁

JIT 대정적 컴파일러

이전 게시물에서 이미 언급했듯이 JIT는 런타임에 IL/바이트코드를 기본 코드로 컴파일할 수 있습니다.그 비용이 언급되었지만 결론은 아닙니다.

JIT에는 모든 것을 컴파일할 수 없다는 큰 문제가 있습니다.JIT 컴파일에는 시간이 걸리므로 JIT는 코드의 일부만 컴파일하는 반면 정적 컴파일러는 전체 기본 바이너리를 생성합니다.어떤 종류의 프로그램에서는 정적 컴파일러가 JIT보다 성능이 쉽게 뛰어납니다.

물론 C#(또는 Java 또는 VB)은 일반적으로 C++보다 실행 가능하고 강력한 솔루션을 생성하는 데 더 빠릅니다(C++에는 복잡한 의미가 있고 C++ 표준 라이브러리는 흥미롭고 강력하지만 전체 라이브러리와 비교할 때 상당히 열악하기 때문입니다). .NET 또는 Java의 표준 라이브러리 범위) 일반적으로 C++와 .NET 또는 Java JIT의 차이점은 대부분의 사용자에게 표시되지 않으며 중요한 바이너리의 경우 여전히 C++ 처리를 호출할 수 있습니다. C# 또는 Java에서(이러한 종류의 기본 호출 자체가 상당히 비용이 많이 들 수 있음에도 불구하고)...

C++ 메타프로그래밍

일반적으로 C++ 런타임 코드를 C# 또는 Java의 해당 코드와 비교합니다.그러나 C++에는 기본적으로 Java/C#보다 성능이 뛰어난 기능이 하나 있는데, 바로 템플릿 메타프로그래밍입니다.코드 처리는 컴파일 시간에 수행되므로(따라서 컴파일 시간이 크게 증가) 런타임이 0(또는 거의 0)이 됩니다.

나는 아직 이것에 대한 실제 효과를 확인하지 못했습니다. (나는 개념만 갖고 놀았지만 그때까지 차이점은 JIT의 실행 시간이 몇 초였고 C++의 경우) 그러나 이는 언급할 가치가 있으며 템플릿 메타프로그래밍이 사소하지 않다는 사실과 함께...

2011-06-10 편집: C++에서 유형을 다루는 작업은 컴파일 타임에 수행됩니다. 즉, 제네릭이 아닌 코드를 호출하는 제네릭 코드를 생성한다는 의미입니다(예:문자열에서 유형 T로의 일반 파서, 인식하는 유형 T에 대한 표준 라이브러리 API를 호출하고 사용자가 파서를 쉽게 확장할 수 있도록 만드는 것은 매우 쉽고 매우 효율적인 반면, Java 또는 C#의 해당 파서는 작성하기가 매우 어렵습니다. 컴파일 타임에 유형이 알려진 경우에도 항상 속도가 느려지고 런타임에 해결됩니다. 희망 JIT가 모든 것을 인라인하는 것입니다.

...

2011-09-20 편집: Blitz++ 팀(홈페이지, 위키피디아) 그런 식으로 진행되었으며 분명히 그들의 목표는 C++ 템플릿 메타 프로그래밍을 통해 런타임 실행에서 컴파일 시간으로 최대한 이동하여 과학 계산에서 FORTRAN의 성능에 도달하는 것입니다.그래서 "나는 아직 이것에 대한 실제 효과를 보았습니다." 분명히 위에서 쓴 부분 하다 실생활에 존재합니다.

네이티브 C++ 메모리 사용량

C++는 Java/C#과 메모리 사용량이 다르므로 장점/결함이 다릅니다.

JIT 최적화에 관계없이 메모리에 대한 직접 포인터 액세스만큼 빠른 것은 없습니다(프로세서 캐시 등은 잠시 무시하겠습니다).따라서 메모리에 연속된 데이터가 있는 경우 C++ 포인터를 통해 해당 데이터에 액세스합니다(예:C 포인터...Caesar에게 기한을 주자)는 Java/C#보다 몇 배 더 빠르게 진행됩니다.그리고 C++에는 RAII가 있어 C#이나 Java보다 많은 처리가 훨씬 쉬워집니다.C++은 필요하지 않습니다 using 개체의 존재 범위를 지정합니다.그리고 C++에는 finally 절.이는 오류가 아닙니다.

:-)

그리고 C# 기본형 구조에도 불구하고 C++ "스택의" 개체는 할당 및 삭제 시 비용이 전혀 들지 않으며 정리를 수행하기 위해 독립 스레드에서 작업하는 데 GC가 필요하지 않습니다.

메모리 조각화의 경우 2008년의 메모리 할당자는 일반적으로 GC와 비교되는 1980년의 오래된 메모리 할당자가 아닙니다.C++ 할당은 메모리에서 이동할 수 없습니다. 사실이지만 Linux 파일 시스템과 마찬가지로 다음과 같습니다.조각화가 발생하지 않는 경우 하드 디스크 조각 모음이 필요한 사람은 누구입니까?올바른 작업에 올바른 할당자를 사용하는 것은 C++ 개발자 툴킷의 일부여야 합니다.이제 할당자를 작성하는 것은 쉽지 않으며 대부분의 사람들은 더 나은 일을 할 수 있으며 대부분의 경우 RAII 또는 GC가 충분합니다.

2011-10-04 편집: 효율적인 할당자에 대한 예는 다음과 같습니다.Windows 플랫폼에서는 Vista 이후부터 낮은 조각화 힙 기본적으로 활성화되어 있습니다.이전 버전의 경우 WinAPI 기능을 호출하여 LFH를 활성화할 수 있습니다. 힙세트정보).다른 OS에서는 대체 할당자가 제공됩니다(참조: https://secure.wikimedia.org/wikipedia/en/wiki/Malloc 목록의 경우)

이제 멀티코어 및 멀티스레딩 기술의 등장으로 메모리 모델이 다소 복잡해지고 있습니다.이 분야에서는 .NET이 유리하고 Java가 우위를 점하고 있다고 들었습니다.일부 "맨 메탈" 해커가 자신의 "기계 근처" 코드를 칭찬하는 것은 쉽습니다.그러나 이제는 컴파일러에게 작업을 맡기는 것보다 손으로 더 나은 어셈블리를 생성하는 것이 훨씬 더 어렵습니다.C++의 경우 10년이 지나면서 컴파일러는 일반적으로 해커보다 더 좋아졌습니다.C# 및 Java의 경우 이는 훨씬 더 쉽습니다.

그럼에도 불구하고 새로운 표준 C++0x는 C++ 컴파일러에 간단한 메모리 모델을 적용하여 C++의 효과적인 다중 처리/병렬/스레딩 코드를 표준화(따라서 단순화)하고 컴파일러를 위한 최적화를 더 쉽고 안전하게 만듭니다.하지만 그 약속이 실현되는지 몇 년 후에 보게 될 것입니다.

C++/CLI 대C#/VB.NET

메모:이 섹션에서는 C++/CLI, 즉 네이티브 C++가 아닌 .NET에서 호스팅되는 C++에 대해 설명합니다.

지난 주에 저는 .NET 최적화에 대한 교육을 받았고 어쨌든 정적 컴파일러가 매우 중요하다는 것을 알게 되었습니다.JIT만큼 중요합니다.

C++/CLI(또는 그 조상인 Managed C++)에서 컴파일된 동일한 코드는 C#(또는 컴파일러가 C#과 동일한 IL을 생성하는 VB.NET)에서 생성된 동일한 코드보다 몇 배 더 빠를 수 있습니다.

C++ 정적 컴파일러는 C#보다 이미 최적화된 코드를 생성하는 데 훨씬 더 뛰어났기 때문입니다.

예를 들어 .NET의 함수 인라인은 바이트 코드 길이가 32바이트보다 작거나 같은 함수로 제한됩니다.따라서 C#의 일부 코드는 JIT에 의해 인라인되지 않는 40바이트 접근자를 생성합니다.C++/CLI의 동일한 코드는 JIT에 의해 인라인되는 20바이트 접근자를 생성합니다.

또 다른 예로는 임시 변수가 있습니다. 이 변수는 C++ 컴파일러에 의해 단순히 컴파일되지만 C# 컴파일러에 의해 생성된 IL에서는 여전히 언급됩니다.C++ 정적 컴파일 최적화로 인해 코드가 줄어들므로 더욱 공격적인 JIT 최적화가 다시 허용됩니다.

그 이유는 C++/CLI 컴파일러가 C++ 네이티브 컴파일러의 광범위한 최적화 기술을 활용했기 때문인 것으로 추측되었습니다.

결론

나는 C++를 좋아한다.

하지만 제가 보기에는 C#이나 Java가 모두 더 나은 선택입니다.C++보다 빠르기 때문이 아니라, 그 품질을 합산하면 결국 C++보다 생산성이 높아지고 교육이 덜 필요하며 더 완전한 표준 라이브러리를 갖게 되기 때문입니다.그리고 대부분의 프로그램의 경우 속도 차이는 (어떤 면에서든) 무시할 수 있을 정도입니다...

편집 (2011-06-06)

C#/.NET에서의 내 경험

저는 이제 5개월 동안 거의 독점적인 전문 C# 코딩을 경험했습니다(이미 C++ 및 Java로 가득 찬 이력서와 약간의 C++/CLI가 추가됩니다).

저는 WinForms(에헴...)와 WCF(멋지네요!), WPF(멋지네요!!!!)를 사용해봤습니다.XAML과 원시 C#을 통해.WPF는 너무 쉬워서 Swing과 비교할 수 없다고 생각합니다.) 및 C# 4.0도 마찬가지입니다.

결론은 C++보다 C#/Java에서 작동하는 코드를 생성하는 것이 더 쉽고 빠르지만 C++보다 C#에서 강력하고 안전하며 견고한 코드를 생성하는 것이 훨씬 더 어렵다는 것입니다(Java에서는 더욱 어렵습니다).이유는 다양하지만 다음과 같이 요약할 수 있습니다.

  1. 제네릭은 템플릿만큼 강력하지 않습니다. (문제를 이해하기 위해 효율적인 일반 Parse 메서드(문자열에서 T로) 또는 C#의 Boost::lexical_cast에 해당하는 효율적인 메서드를 작성해 보세요.)
  2. RAII는 여전히 타의 추종을 불허합니다 (GC는 여전히 누수될 수 있으며(예, 그 문제를 처리해야 했습니다) 메모리만 처리합니다.C#조차도 using 올바른 Dispose 구현을 작성하는 것이 어렵기 때문에 쉽고 강력하지 않습니다.)
  3. 씨# readonly 그리고 자바 final C++만큼 유용한 곳은 없습니다 const (C++에 기본 제공되는 기능이지만 엄청난 작업 없이 C#에서 읽기 전용의 복잡한 데이터(예: 노드 트리)를 노출할 수 있는 방법은 없습니다.불변 데이터는 흥미로운 솔루션이지만 모든 것을 불변으로 만들 수는 없으므로 아직 충분하지 않습니다.).

따라서 C#은 작동하는 것을 원하는 한 즐거운 언어로 남아 있지만 원하는 순간에는 실망스러운 언어로 남아 있습니다. 항상 안전하게 공장.

Java는 C#과 동일한 문제를 안고 있으며 다음과 같은 문제가 더 많기 때문에 훨씬 더 실망스럽습니다.C#과 동등한 기능이 부족함 using 키워드, 내 매우 숙련된 동료는 리소스가 올바르게 해제되었는지 확인하는 데 너무 많은 시간을 소비했지만 C++에서는 해당 키워드가 쉬웠을 것입니다(소멸자와 스마트 포인터 사용).

따라서 대부분의 코드에서 C#/Java의 생산성 향상이 눈에 띄는 것 같습니다.코드가 최대한 완벽해야 하는 그날까지.그날 당신은 고통을 알게 될 것입니다.(당신은 우리 서버와 GUI 앱에서 요청한 내용을 믿지 못할 것입니다...).

서버측 Java 및 C++ 정보

저는 건물 반대편에 있는 서버 팀(그들 중에서 2년 동안 근무한 후 GUI 팀으로 돌아왔습니다)과 계속 연락하면서 흥미로운 것을 배웠습니다.

지난 몇 년 동안 Java에는 많은 프레임워크/도구가 있고 유지 관리, 배포 등이 쉽기 때문에 Java 서버 앱이 기존 C++ 서버 앱을 대체하도록 하는 것이 추세였습니다.등..

...최근 몇 달 동안 지연 시간 문제가 추악한 대두를 겪기 전까지는 말이죠.그런 다음 숙련된 Java 팀이 시도한 최적화에 관계없이 Java 서버 앱은 실제로 최적화되지 않은 기존 C++ 서버와의 경쟁에서 간단하고 깔끔하게 패했습니다.

현재 결정은 성능이 여전히 중요하지만 낮은 대기 시간 목표에 관심이 없는 일반적인 사용을 위해 Java 서버를 유지하고 낮은 대기 시간 및 초저 대기 시간 요구에 맞게 이미 더 빠른 C++ 서버 애플리케이션을 적극적으로 최적화하는 것입니다.

결론

예상만큼 간단한 것은 없습니다.

Java와 C#은 광범위한 표준 라이브러리와 프레임워크를 갖춘 멋진 언어로, 빠르게 코딩하고 결과를 곧 얻을 수 있습니다.

그러나 원시적인 성능, 강력하고 체계적인 최적화, 강력한 컴파일러 지원, 강력한 언어 기능 및 절대적인 안전성이 필요한 경우 Java 및 C#은 경쟁 우위를 유지하는 데 필요한 마지막 누락되었지만 중요한 품질 비율을 확보하기 어렵게 만듭니다.

평균적인 품질의 코드를 생성하려면 C++보다 C#/Java에서 더 적은 시간과 경험이 부족한 개발자가 필요하지만, 반면에 완벽한 품질의 코드를 만들기 위해 탁월함이 필요한 순간 ​​갑자기 결과를 얻는 것이 더 쉽고 빨라졌습니다. 바로 C++에서요.

물론 이것은 내 자신의 인식이며 아마도 우리의 특정한 요구에 국한될 수 있습니다.

하지만 오늘날 GUI 팀과 서버 측 팀 모두에서 이런 일이 일어나고 있습니다.

물론, 새로운 일이 생기면 이 게시물을 업데이트하겠습니다.

편집 (2011-06-22)

"우리는 성능과 관련하여 C ++가 큰 마진으로 승리한다는 것을 알게됩니다.그러나 가장 광범위한 튜닝 노력이 필요했으며, 그 중 다수는 평균 프로그래머가 이용할 수없는 수준의 정교함에서 수행되었습니다.

[...] Java 버전은 아마도 구현하기가 가장 간단했지만 성능 분석이 가장 어려웠을 것입니다.특히 가비지 수집과 관련된 영향은 복잡하고 조정하기가 매우 어려웠습니다."

출처:

편집 (2011-09-20)

"페이스북에서 떠오르는 단어는 '합리적으로 작성된 C++ 코드는 빠르게 실행됩니다.' 이는 PHP 및 Java 코드를 최적화하는 데 엄청난 노력을 기울인 것을 강조합니다.역설적이게도 C++ 코드는 다른 언어보다 작성하기가 더 어렵습니다. 효율적인 코드는 [다른 언어보다 C++로 작성하는 것이] 훨씬 쉽습니다."

허브 서터 ~에 //짓다/, 인용 안드레이 알렉산드레스쿠

출처:

관리 대 관리와 관리되지 않는 성능에 대해 이야기 할 때마다 Rico (및 Raymond)가 C ++ 및 C# 버전의 중국어/영어 사전을 비교 한 시리즈를 지적하고 싶습니다. 이것 구글 검색 당신이 스스로 읽을 수 있지만, 나는 Rico의 요약을 좋아합니다.

그래서 나는 내 분쇄 패배로 부끄러워합니까? 거의 ~ 아니다. 관리 된 코드는 거의 노력이 거의없는 결과를 얻었습니다. 관리되는 레이몬드를 물리 치려면 :

  • 자신의 파일 I/O 물건을 작성하십시오
  • 자신의 문자열 클래스를 작성하십시오
  • 자신의 할당자를 작성하십시오
  • 자신의 국제지도를 작성하십시오

물론 그는 이용 가능한 하위 레벨 라이브러리를 사용하여이를 수행했지만 여전히 많은 작업입니다. 남은 STL 프로그램을 부를 수 있습니까? 나는 그렇게 생각하지 않습니다. 나는 그가 결코 문제가되지 않았던 std :: 벡터 클래스를 유지했다고 생각하고 그는 찾은 기능을 유지했습니다. 거의 모든 것이 사라졌습니다.

그래서, 그래, 당신은 CLR을 확실히 이길 수 있습니다. Raymond는 그의 프로그램을 더 빨리 만들 수 있습니다.

흥미롭게도, 두 프로그램 내부 타이머에 의해보고 된대로 파일을 구문 분석하는 시간은 거의 동일합니다. 차이는 오버 헤드입니다.

저에게 결론은 관리되지 않은 버전이 원래의 관리되지 않은 코드의 간단한 포트 인 관리 버전을이기는 데 6 개의 개정이 걸렸다는 것입니다. 마지막 성능이 필요한 경우 (그리고 그것을 얻을 시간과 전문 지식이 필요하다면, 당신은 관리하지 않아야하지만, 저에게는 33 개 이상의 첫 버전에서의 순서대로 이점을 얻을 것입니다. % 6 번 시도하면 얻습니다.

특정 CPU 최적화를위한 컴파일은 일반적으로 과대 평가됩니다. C ++로 프로그램을 마시고 Pentium Pro에 대한 최적화와 함께 컴파일하고 Pentium 4에서 실행 한 다음 Pentium 4를 위해 최적화로 다시 컴파일하십시오. 나는 여러 프로그램으로 오후를 통과했습니다. 일반적인 결과 ?? 일반적으로 2-3% 미만의 성능이 증가합니다. 따라서 이론적 JIT 장점은 거의 없습니다. 성능의 대부분의 차이는 스칼라 데이터 처리 기능을 사용할 때만 관찰 할 수 있습니다. 그런 종류의 최적화는 느리고 비용이 많이 들며 때로는 JIT에 부적합한 경우가 있습니다.

실제 세계 및 실제 응용 프로그램에서 C ++는 일반적으로 Java보다 더 빠릅니다. 주로 메모리 발자국이 가벼워 캐시 성능이 향상되기 때문입니다.

그러나 모든 C ++ 기능을 사용하려면 개발자가 열심히 노력해야합니다. 우수한 결과를 얻을 수 있지만 뇌를 사용해야합니다. C ++는 더 많은 도구를 제시하기로 결정한 언어로, 언어를 잘 사용할 수 있도록 배워야하는 가격을 청구합니다.

JIT (단지 시간 컴파일)는 대상 플랫폼에 최적화되기 때문에 엄청나게 빠를 수 있습니다.

즉, 개발자가 코드를 작성하는 CPU에 관계없이 CPU가 지원할 수있는 컴파일러 트릭을 활용할 수 있습니다.

.NET JIT의 기본 개념은 다음과 같이 작동합니다 (크게 단순화).

처음으로 메소드 호출 :

  • 귀하의 프로그램 코드는 메소드 foo ()를 호출합니다.
  • CLR은 foo ()를 구현하는 유형을보고 그것과 관련된 메타 데이터를 가져옵니다.
  • 메타 데이터에서 CLR은 IL (중간 바이트 코드)이 저장되는 메모리 주소를 알고 있습니다.
  • CLR은 메모리 블록을 할당하고 JIT를 호출합니다.
  • JIT는 IL을 기본 코드로 컴파일하고 할당 된 메모리에 배치 한 다음 Foo ()의 유형 메타 데이터에서 함수 포인터를 변경 하여이 기본 코드를 가리 킵니다.
  • 기본 코드가 실행되었습니다.

두 번째로 메소드 호출 :

  • 귀하의 프로그램 코드는 메소드 foo ()를 호출합니다.
  • CLR은 foo ()를 구현하는 유형을보고 메타 데이터에서 함수 포인터를 찾습니다.
  • 이 메모리 위치의 기본 코드는 실행됩니다.

보시다시피, 실시간 최적화의 장점을 제외하고는 두 번째 시간이 C ++와 거의 동일한 프로세스입니다.

즉, 관리 언어를 늦추는 다른 오버 헤드 문제가 여전히 있지만 JIT는 많은 도움이됩니다.

좋아요 오리온 아드리안대답이지만 또 다른 측면이 있습니다.

어셈블리 언어 대 Fortran과 같은 "인간"언어에 대해 같은 질문이 수십 년 전에 제기되었습니다. 그리고 대답의 일부는 비슷합니다.

예, C ++ 프로그램은 주어진 (사소한?) 알고리즘에서 C#보다 빠를 수 있지만 C#의 프로그램은 종종 C ++의 "순진한"구현보다 빠르거나 빠르며 C ++의 최적화 된 버전보다 빠르거나 빠릅니다. 개발하는 데 시간이 더 걸리며 여전히 C# 버전을 매우 작은 마진으로 이길 수 있습니다. 그래서, 정말 그만한 가치가 있습니까?

당신은 그 질문에 일대일로 답변해야합니다.

즉, 나는 C ++의 오랜 팬이며, 때로는 너무 표현력이 뛰어나고 강력한 언어라고 생각합니다. 그러나 많은 "실생활"문제 (개인적으로는 "내가 해결하기 위해 지불하는 종류"를 의미합니다), C#은 더 빨리 더 안전하고 안전하게 이루어집니다.

당신이 지불하는 가장 큰 형벌? 많은 .NET 및 Java 프로그램은 메모리 호그입니다. .NET 및 Java 앱은 비슷한 복잡성의 C ++ 프로그램이 MBS의 "수십"을 거의 긁지 않을 때 "수백"메가 바이트의 메모리를 사용하는 것을 보았습니다.

핫스팟을 사용하더라도 Java 코드가 C ++보다 빠르게 실행된다는 것을 얼마나 자주 알지 못하지만, 어떻게 될 수 있는지 설명하는 데 스윙을 할 것입니다.

JVM의 해석 된 기계 언어로 컴파일 된 Java 코드를 생각해보십시오. 핫스팟 프로세서가 컴파일 된 코드의 특정 부분이 여러 번 사용될 것이라는 사실을 알게되면 기계 코드에서 최적화를 수행합니다. 핸드 튜닝 어셈블리는 C ++ 컴파일 코드보다 거의 항상 빠르기 때문에 프로그래밍 방식으로 조정 된 기계 코드가 ~도 나쁜.

따라서 반복적 인 코드의 경우 핫스팟 JVM이 가비지 수집이 시작될 때까지 핫스팟 JVM이 C ++보다 더 빨리 Java를 실행할 수있는 위치를 알 수있었습니다. :)

일반적으로 귀하의 프로그램 연산 응용 프로그램의 속도에 훨씬 더 중요합니다. 언어. C ++를 포함하여 모든 언어로 열악한 알고리즘을 구현할 수 있습니다. 이를 염두에두고 일반적으로보다 효율적인 알고리즘을 구현하는 데 도움이되는 언어로 더 빠르게 실행되는 코드를 작성할 수 있습니다.

고급 언어는 비효율적 인 코드를 피하는 데 도움이되는 많은 효율적인 사전 구축 데이터 구조에 쉽게 액세스 할 수 있고 장려하는 관행을 제공함으로써 매우 효과적입니다. 물론, 그들은 때때로 실제로 느린 코드를 쉽게 작성할 수있게 만들 수 있으므로 여전히 플랫폼을 알아야합니다.

또한 C ++는 STL 컨테이너, 자동 포인터 등과 같은 "새로운"(인용문) 기능을 따라 잡습니다. 예를 들어 Boost 라이브러리를 참조하십시오. 또한 일부 작업을 수행하는 가장 빠른 방법에는 고급 언어로 금지 된 포인터 산술과 같은 기술이 필요하다는 것을 알 수 있습니다. .

가장 중요한 것은 당신이 사용하는 언어, 관련 API, 그것이 할 수있는 것, 그리고 그 제한 사항을 아는 것입니다.

나도 모르겠어요 ... 내 Java 프로그램은 항상 느립니다. :-) 나는 C# 프로그램이 특히 느리다는 것을 결코 눈치 채지 못했습니다.

다음은 또 다른 intersting 벤치 마크가 있습니다.이 벤치 마크는 자신의 컴퓨터에서 스스로 시도 할 수 있습니다.

ASM, VC ++, C#, Silverlight, Java Applet, JavaScript, Flash (AS3)를 비교합니다.

Roozz 플러그인 속도 데모

JavaScript의 속도는 브라우저가 실행중인 브라우저에 따라 많이 다양합니다. 이 플러그인은 호스팅 브라우저와 동일한 프로세스에서 실행되기 때문에 Flash 및 Silverlight에서도 마찬가지입니다. 그러나 Roozz 플러그인은 자체 프로세스에서 실행되는 표준 .Exe 파일을 실행하므로 속도는 호스팅 브라우저의 영향을받지 않습니다.

"보다 더 잘 수행하는 것"을 정의해야합니다. 글쎄, 나는 당신이 속도에 대해 물었지만, 그 모든 것이 중요하지는 않습니다.

  • 가상 머신이 더 많은 런타임 오버 헤드를 수행합니까? 예!
  • 그들은 더 많은 작업 기억을 먹습니까? 예!
  • 시작 비용이 더 높습니까 (런타임 초기화 및 JIT 컴파일러)? 예!
  • 거대한 라이브러리가 설치되어 있습니까? 예!

그리고 그 편견이 있습니다. 그렇습니다;)

C# 및 Java를 사용하면 얻는 것에 대한 가격을 지불합니다 (더 빠른 코딩, 자동 메모리 관리, 큰 라이브러리 등). 그러나 세부 사항에 대해 흥정 할 여지가별로 없습니다. 완전한 패키지를 가져 가거나 아무것도 가져 가지 않습니다.

해당 언어가 컴파일 된 코드보다 빠르게 실행하도록 일부 코드를 최적화 할 수 있더라도 전체 접근 방식은 (IMHO) 비효율적입니다. 트럭으로 매일 직장까지 5 마일 떨어진 곳에서 운전하는 것을 상상해보십시오! 편안하고 기분이 좋고 안전합니다 (극단적 인 크럼프 존). 한동안 가스를 밟은 후에는 표준 자동차만큼 빠릅니다! 왜 우리 모두는 일하러 운전할 트럭을 가지고 있지 않습니까? ;)

C ++에서 당신은 당신이 지불하는 것을 더 이상 얻지 못합니다.

Bjarne Stroustrup 인용 : "C ++는 제가 가장 좋아하는 쓰레기 수집 언어입니다.링크 텍스트

Java 또는 C# 컴파일러에서 생성 된 실행 가능한 코드는 해석되지 않습니다. "JIT (Just Intment) (JIT) 기본 코드로 컴파일됩니다. 따라서 실행 중에 Java/C# 프로그램의 첫 번째 코드가 발생하면 "런타임 컴파일러"(일명 JIT 컴파일러)가 바이트 코드 (Java) 또는 IL 코드 (C#)를 기본 시스템 지침으로 바꾸면 약간의 오버 헤드가 있습니다. 그러나 다음에 애플리케이션이 실행되는 동안 코드가 발생하면 기본 코드가 즉시 실행됩니다. 이것은 일부 Java/C# 프로그램이 처음에는 어떻게 느리게 보이는지 설명하지만 더 오래 실행할수록 더 잘 수행 할 수 있습니다. 좋은 예는 ASP.NET 웹 사이트입니다. 웹 사이트에 처음 액세스 할 때 C# 코드가 JIT 컴파일러에 의해 기본 코드로 컴파일되므로 약간 느리게 될 수 있습니다. 후속 액세스는 서버와 클라이언트 측 캐싱을 제쳐두고 훨씬 빠른 웹 사이트를 만듭니다.

당신이 요청한 특정 질문에 대한 좋은 답변. 물러서서 더 큰 그림을보고 싶습니다.

사용자의 소프트웨어 속도에 대한 사용자의 인식은 CodeGen이 얼마나 잘 최적화되는지보다 다른 많은 요소의 영향을받습니다. 여기 몇 가지 예가 있어요.

  • 수동 메모리 관리는 올바르게 수행하기 어렵고 (누출 없음) 효력을 발휘하기가 더 어렵습니다 (완료 직후 무료 메모리). GC를 사용하는 것은 일반적으로 메모리를 잘 관리하는 프로그램을 제작할 가능성이 더 높습니다. GC를 능가하기 위해 매우 열심히 일하고 소프트웨어 제공을 지연시킬 의향이 있습니까?

  • 내 C#은 내 C ++보다 읽고 이해하기가 더 쉽습니다. 또한 내 C# 코드가 올바르게 작동하고 있음을 스스로 확신시킬 수있는 더 많은 방법이 있습니다. 즉, 버그를 도입 할 위험이 줄어든 알고리즘을 최적화 할 수 있습니다 (사용자는 빠르게 충돌하는 소프트웨어를 좋아하지 않습니다.)

  • C ++보다 C#에서 소프트웨어를 더 빨리 만들 수 있습니다. 이로 인해 성능 작업을 수행 할 시간이 다가오고 여전히 제 시간에 내 소프트웨어를 제공합니다.

  • C ++보다 C#로 좋은 UI를 작성하는 것이 더 쉽기 때문에 UI가 반응 형을 유지하는 동안 또는 프로그램이 한동안 차단되어야 할 때 진행 상황이나 hearbeat ui를 제공하는 동안 백그라운드로 작업을 푸시 할 수있을 가능성이 높습니다. 이것은 더 빨리 만드는 것은 아니지만 사용자가 기다리는 것에 대해 더 행복하게 만듭니다.

내가 C#에 대해 말한 모든 것은 아마도 Java에게는 사실 일 것입니다. 나는 확실히 말할 경험이 없습니다.

Java/C# 프로그래머를 학습하는 C ++라면 Java/C#의 관점에서 계속 생각하고 구두를 C ++ 구문으로 번역하려는 유혹을받을 것입니다. 이 경우 기본 코드 대 해석/JIT의 앞에서 언급 한 이점 만 얻을 수 있습니다. C ++ 대 Java/C#에서 가장 큰 성능 이득을 얻으려면 C ++의 강점을 활용하기 위해 C ++ 및 디자인 코드에서 생각하는 법을 배워야합니다.

역설에 Edsger dijkstra: [당신의 첫 번째 언어]는 회복을 넘어 마음을 절단합니다.
역설에 제프 아트 우드: 당신은 새로운 언어로 [모국어]를 쓸 수 있습니다.

가장 중요한 JIT 최적화 중 하나는 메소드 인라인입니다. Java는 런타임 정확성을 보장 할 수 있다면 가상 메소드를 인라인 할 수 있습니다. 이러한 종류의 최적화는 일반적으로 전체 프로그램 분석이 필요하기 때문에 표준 정적 컴파일러에서 수행 할 수 없습니다. 이는 별도의 컴파일로 인해 어려운 것입니다 (대조적으로 JIT는 모든 프로그램을 사용할 수 있습니다). 메소드 인 라이닝은 다른 최적화를 향상시켜 최적화 할 수있는 더 큰 코드 블록을 제공합니다.

Java/C#의 표준 메모리 할당도 더 빠르며 거래 (GC)는 훨씬 느리지 않지만 결정 론적입니다.

가상 머신 언어는 컴파일 된 언어를 능가 할 가능성이 낮지 만 다음과 같은 이유는 (적어도 C#을 본 적이 없기 때문에 여기서 Java에 대해 말하고 있기 때문에) 중요하지 않을 정도로 가까이 갈 수 있습니다.

1/ Java 런타임 환경은 일반적으로 자주 실행되는 코드 조각을 감지하고 해당 섹션의 JIT (Jive-In-Time) 컴파일을 수행하여 향후 전체 컴파일 된 속도로 실행되도록합니다.

Java 라이브러리의 방대한 부분이 편집되어 라이브러리 기능을 호출 할 때 해석되지 않은 컴파일 된 코드를 실행할 수 있습니다. OpenJDK를 다운로드하여 코드 (C)를 볼 수 있습니다.

3/ 대규모 계산을하지 않는 한 프로그램이 실행중인 시간의 대부분은 매우 느리게 (비교적 말하면) 인간의 입력을 기다리고 있습니다.

4/ 클래스를로드 할 때 Java 바이트 코드의 많은 검증이 수행되므로 런타임 검사의 정상적인 오버 헤드가 크게 줄어 듭니다.

5/ 최악의 경우, 성능 집약적 코드는 컴파일 된 모듈로 추출하여 Java (JNI 참조)에서 호출하여 최고 속도로 실행될 수 있습니다.

요약하면, Java Bytecode는 기본 기계 언어를 능가하지는 않지만이를 완화하는 방법이 있습니다. Java의 큰 장점 (내가 볼 수 있듯이)은 거대한 표준 라이브러리 및 크로스 플랫폼 특성.

오리온 아드리안, C ++에 대해서도 많은 말을 할 수 있기 때문에 귀하의 발언이 얼마나 근거가 있는지 확인하기 위해 귀하의 게시물을 뒤집겠습니다. 그리고 Java/C# 컴파일러가 빈 함수를 최적화한다고 말하면 실제로 당신이있는 것처럼 들리게됩니다. ~ 아니다 a) 실제 프로그램에 실제로 나쁜 레거시 코드를 제외하고는 빈 기능이 포함되어 있어야하는 이유, b) 실제로 흑인과 출혈 에지 최적화가 아닌 이유가 있기 때문에 최적화 전문가.

그 문구 외에, 당신은 포인터에 대해 끔찍하게 도망 쳤지 만 Java와 C#에서 반대하는 것은 기본적으로 C ++ 포인터처럼 작동하지 않습니까? 그들이 겹치지 않을 수 있습니까? 그들이 null이 아닐 수 있습니까? C (및 대부분의 C ++ 구현)에는 제한 키워드가 있으며, 둘 다 값 유형을 가지고 있으며 C ++는 널 보증이 아닌 참조-값을 가지고 있습니다. Java와 C#은 무엇을 제공합니까?

>>>>>>>>>>

일반적으로 C 및 C ++는 배포 전에 코드를 컴파일하는 컴파일러 인 AOT 컴파일러가 많은 코어 빌드 서버에서 C# 컴파일 된 프로그램을 최적화 할 수 있기 때문에 빠르거나 빠를 수 있습니다. 그렇게 할 시간이 많기 때문일 수 없습니다. 컴파일러는 기계가 인텔인지 AMD인지 확인할 수 있습니다. 펜티엄 4, 코어 솔로 또는 코어 듀오; 또는 SSE4 등을 지원하고 컴파일러가 런타임 발송을 지원하지 않으면 소수의 전문 바이너리를 배포하여 직접 해결할 수 있습니다.

AC# 프로그램은 일반적으로 실행 중에 일반적으로 컴파일되어 모든 컴퓨터에서 괜찮게 실행되지만 단일 구성 (예 : 프로세서, 명령 세트, 기타 하드웨어)에 적합한만큼 최적화되지는 않습니다. ~ 해야 하다 먼저 시간을 보내십시오. 루프 핵분열, 루프 반전, 자동 벡터화, 전체 프로그램 최적화, 템플릿 확장, IPO 등과 같은 기능은 최종 사용자를 괴롭히지 않는 방식으로 모두 해결하기가 매우 어렵습니다.

또한 특정 언어 기능을 사용하면 C ++ 또는 C의 컴파일러가 코드에 대한 가정을하여 Java/C# 컴파일러가 수행 할 수없는 특정 부품을 최적화 할 수 있습니다. 전체 유형의 제네릭 ID 또는 보장 된 프로그램 흐름에 액세스 할 수 없으면 안전하지 않은 많은 최적화가 있습니다.

또한 C ++ 및 C는 단 하나의 레지스터 증분으로 한 번에 많은 스택 할당을 수행합니다. 이는 가비지 수집기와 코드 간의 추상화 계층과 같이 Javas 및 C# 할당보다 더 효율적입니다.

이제이 다음 지점에서 Java에 대해 말할 수는 없지만, 예를 들어 C ++ 컴파일러는 메소드의 본문이 비어 있음을 알면 메소드와 메소드 호출을 실제로 제거 할 것이라는 것을 알고 있습니다. 최적의 레지스터 사용량을 찾으려면 바운드 검사를 시행하지 않으면 루프와 내부 루프를 자동으로 변형시키고 내부를 바깥쪽으로 반전시키고 루프에서 조건부를 움직이고 루프를 분할하고 풀립니다. C 웨이를 수행 할 때 STD :: 벡터를 기본 제로 오버 헤드 어레이로 확장합니다. 그것은 절차 적 최적화를 수행합니다. 발신자 사이트에서 직접 반환 값을 구성합니다. 표현을 접고 전파합니다. 캐시 친화적 인 방식으로 데이터를 재정렬합니다. 점프 스레딩이됩니다. 런타임 제로 오버 헤드로 컴파일 타임 레이 트레이서를 작성할 수 있습니다. 매우 비싼 그래프 기반 최적화를 만듭니다. 그것은 강도 감소를 수행 할 것이며, 특정 코드를 구문 적으로 완전히 불평등하지만 의미 적으로 동등한 코드로 대체 할 것입니다 (오래된 "Xor Foo, foo"는 가장 간단하지만, 그러한 종류의 오래된 최적화). 친절하게 물어 보면 IEEE 플로팅 포인트 표준을 생략하고 부동 소수점 오페라 재주문과 같은 더 많은 최적화를 가능하게 할 수 있습니다. 코드를 마사지하고 학살 한 후에는 전체 프로세스를 반복 할 수 있습니다. 종종 특정 최적화가 특정 최적화를위한 기초를 마련하기 때문입니다. 또한 셔플 매개 변수로 다시 시도하고 다른 변형이 내부 순위에서 어떻게 점수를 얻는 지 볼 수 있습니다. 코드 전체에 이런 종류의 논리를 사용합니다.

보시다시피, 특정 C ++ 또는 C 구현이 더 빨라질 이유가 많이 있습니다.

이제이 모든 것이 C ++에서 많은 최적화를 만들어 C#, 특히 숫자 크런치, 실시간 및 금속 영역에서 할 수있는 모든 것을 날려 버릴 수 있지만 독점적으로는 그렇지 않습니다. 먼 길을 찾기 위해 단일 포인터를 만질 필요조차 없습니다.

그래서 당신이 쓰는 것에 따라 나는 하나 또는 다른 사람과 함께 갈 것입니다. 그러나 하드웨어 의존적이지 않은 것을 쓰고 있다면 (드라이버, 비디오 게임 등) C#의 성능에 대해 걱정하지 않을 것입니다 (다시 Java에 대해 말할 수 없습니다). 괜찮을거야.

<<<<<<<<<<

일반적으로 특정 일반적인 인수는 특정 게시물에서 시원하게 들릴 수 있지만 일반적으로 신뢰할 수있는 것은 아닙니다.

어쨌든 평화를 이루기 위해 : aot 그대로 훌륭합니다 jit. 유일한 정답은 다음과 같습니다. 그리고 진정한 똑똑한 사람들은 당신이 어쨌든 두 세계의 최고를 사용할 수 있다는 것을 알고 있습니다.

Java 통역사가 실제로 기계 코드를 생성하는 경우에만 발생합니다. 더 나은 컴퓨터가 컴파일러가 작성하는 C ++ 코드에 대해 C ++ 코드가 Java보다 느려지는 지점 및 해석 비용까지 최적화되었습니다.

그러나 실제로 일어나는 가능성은 상당히 낮습니다. Java가 잘 쓰여진 라이브러리가없고 자신의 잘못 쓰여진 C ++ 라이브러리가 없다면.

실제로 C#은 Java와 같은 가상 시스템에서 실제로 실행되지 않습니다. IL은 완전히 기본 코드이며 기본 코드와 동일한 속도로 실행되는 어셈블리 언어로 컴파일됩니다. JIT 비용을 완전히 제거하는 .NET 응용 프로그램을 사전 제트 한 다음 완전히 기본 코드를 실행하고 있습니다.

.NET 코드의 속도는 .NET 코드가 느리기 때문에 발생하는 것이 아니라 쓰레기 수집, 참조 확인, 완전한 스택 프레임을 저장하는 등의 작업을 수행하기 위해 무대 뒤에서 훨씬 더 많은 일이 발생하기 때문입니다. 이것은 매우 강력하고 도움이 될 수 있습니다. 응용 프로그램을 구축하지만 비용도 제공합니다. C ++ 프로그램에서도 이러한 모든 작업을 수행 할 수 있습니다 (Core .NET 기능의 대부분은 실제로 .NET 코드이며 로터에서 볼 수 있습니다). 그러나 손으로 동일한 기능을 작성하면 .NET 런타임이 최적화되고 미세하게 조정 되었기 때문에 훨씬 느린 프로그램으로 끝날 것입니다.

즉, 관리 코드의 강점 중 하나는 완전히 검증 될 수 있다는 것입니다. 코드가 다른 프로세스의 메모리에 액세스하지 않거나 실행하기 전에 코드가 절대로 수행되지 않는지 확인할 수 있습니다. Microsoft는 완전히 관리되는 운영 체제의 연구 프로토 타입을 보유하고 있으며, 100% 관리 환경은이 검증을 활용하여 관리되는 프로그램이 더 이상 필요하지 않은 보안 기능을 끄면 현대 운영 체제보다 실제로 현대 운영 체제보다 훨씬 더 빠르게 성능을 발휘할 수 있음을 보여주었습니다. (우리는 어떤 경우에는 10 배처럼 말하고 있습니다). SE Radio는이 프로젝트에 대해 이야기하는 훌륭한 에피소드를 가지고 있습니다.

경우에 따라 관리 코드는 실제로 될 수 있습니다 더 빠르게 기본 코드보다. 예를 들어, "Mark-and-Sweep"쓰레기 수집 알고리즘은 JRE 또는 CLR과 같은 환경이 단일 패스에서 많은 수의 짧은 수명 (보통) 객체를 무료로 제공 할 수 있습니다. 시간.

에서 위키 백과:

많은 실용적인 목적을 위해 수집 된 언어로 구현 된 할당/거래 집약적 알고리즘은 수동 힙 할당을 사용하는 등가물보다 실제로 더 빠를 수 있습니다. 이에 대한 주요 이유는 쓰레기 수집기가 런타임 시스템이 잠재적으로 유리한 방식으로 할당 및 거래 작업을 상각 할 수 있기 때문입니다.

즉, 나는 많은 C#과 C ++를 많이 썼고 많은 벤치 마크를 실행합니다. 내 경험상, C ++는 C#보다 훨씬 빠릅니다. 경향이 있습니다 더 빨리. 얼마나 빨리? 글쎄, 그것은 많이 다양하지만 100% 속도 향상을 보는 것은 드문 일이 아닙니다. (2) 경우에 따라 쓰레기 수집은 대단히 관리되는 응용 프로그램을 늦추십시오. .NET CLR은 큰 힙 (예 :> 2GB)으로 끔찍한 작업을 수행하며, 중간 수명 범위가 적거나 객관적이지 않은 응용 분야에서도 GC에서 많은 시간을 소비 할 수 있습니다.

물론, 내가 겪은 대부분의 경우 관리 언어는 긴 샷으로 충분히 빠르며 C ++의 추가 성능을위한 유지 보수 및 코딩 트레이드 오프는 단순히 좋은 것이 아닙니다.

흥미로운 벤치 마크가 있습니다http://zi.fi/shootout/

실제로 Sun 's Hotspot JVM은 "Mixed-Mode"실행을 사용합니다. 특정 코드 블록 (메소드, 루프, 트리 캐치 블록 등)이 많이 실행될 것이라고 결정할 때까지 메소드의 바이트 코드를 해석하면 JIT가 컴파일됩니다. JIT를 컴파일하는 데 필요한 시간은 방법이 거의 실행되지 않는 방법 인 경우 방법을 해석하는 것보다 종종 더 오래 걸립니다. JVM은 거의 실행되지 않는 JITING 코드를 낭비하지 않기 때문에 일반적으로 "Mixed-Mode"의 성능이 높습니다. C# 및 .NET 은이 작업을 수행하지 않습니다. .NET은 종종 시간을 낭비하는 모든 것을 jits합니다.

HP Labs에 대해 읽으십시오. 발전기, PA-8000에서 실행되는 PA-8000의 통역사는 종종 기본보다 빠른 프로그램을 운영합니다. 그렇다면 그것은 전혀 놀라운 것처럼 보이지 않습니다!

그것을 "중간 단계"라고 생각하지 마십시오. 프로그램을 실행하려면 이미 어떤 언어로든 다른 많은 단계가 포함됩니다.

그것은 종종 다음으로 나옵니다.

  • 프로그램은 핫스팟이 있으므로 실행 해야하는 코드의 95%를 실행하는 속도가 느려도 5%가 더 빠르면 여전히 성능 경쟁력이 있습니다.

  • HLL은 C/C ++와 같은 LLL보다 귀하의 의도에 대해 더 많이 알고 있으므로보다 최적화 된 코드를 생성 할 수 있습니다 (OCAML은 훨씬 더 많으며 실제로는 종종 더 빠릅니다).

  • JIT 컴파일러에는 정적 컴파일러가하지 않는 많은 정보가 있습니다 (이 시간에 발생하는 실제 데이터와 마찬가지로)

  • JIT 컴파일러는 런타임에 전통적인 링커가 실제로 허용되지 않는 최적화를 수행 할 수 있습니다 (공동 사례가 평평하거나 라이브러리 호출이 평평 해지므로 분기를 재정렬하는 것과 같이)

대체로 C/C ++는 성능을위한 매우 유쾌한 언어입니다. 데이터 유형에 대한 정보가 거의없고 데이터에 대한 정보가 없으며 런타임 최적화를 방해 할 수있는 동적 런타임이 없습니다.

Java 또는 CLR이 C ++보다 빠르면 짧은 파열이 발생할 수 있지만 응용 프로그램 수명은 전반적으로 성능이 나빠질 수 있습니다. www.codeproject.com/kb/dotnet/runtimeperformance.aspx를 참조하십시오.

Cliff의 답변은 다음과 같습니다. 클릭하십시오. http://www.azulsystems.com/blog/cliff/2009-09-06-java-vs-c-performanceagain

내 이해는 C/C ++가 특정 기계 아키텍처에서 실행될 기본 코드를 생성한다는 것입니다. 반대로, Java 및 C#과 같은 언어는 가상 시스템 위에 실행되어 기본 아키텍처를 추상화합니다. 논리적 으로이 중간 단계로 인해 Java 또는 C#이 C ++의 속도와 일치하는 것은 불가능 해 보이지만 최신 컴파일러 ( "핫 스팟") 가이 속도를 얻거나 심지어 초과 할 수 있다고 들었습니다.

그것은 비논리적입니다. 중간 표현의 사용이 본질적으로 성능 저하되지는 않습니다. 예를 들어, LLVM-GCC는 LLVM IR (가상 무한 등록 기계)을 통해 C 및 C ++를 기본 코드로 컴파일하며 탁월한 성능 (종종 GCC를 제치)을 달성합니다.

아마도 이것은 언어 질문보다 컴파일러 질문이지만, 누구나 일반 영어로 이러한 가상 기계 언어 중 하나가 모국어보다 더 잘 수행 할 수있는 방법을 설명 할 수 있습니까?

여기 몇 가지 예가 있어요.

  • JIT 컴파일이있는 가상 머신은 런타임 코드 생성을 용이하게합니다 (예 : System.Reflection.Emit .NET)에서 C# 및 F#과 같은 언어로 생성 된 코드를 정리할 수는 있지만 C 또는 C ++에서 비교적 슬로우 통역사를 작성하는 데 의지해야합니다. 예를 들어, 정규식을 구현합니다.

  • 가상 머신의 일부 (예 : 쓰기 배리어 및 할당 자)는 종종 손으로 코딩 된 어셈블러로 작성됩니다. C 및 C ++는 충분히 빠른 코드를 생성하지 않기 때문입니다. 프로그램이 시스템의 이러한 부분을 강조하면 C 또는 C ++로 작성할 수있는 모든 것을 능가 할 수 있습니다.

  • 기본 코드의 동적 링크는 성능을 방해하고 전체 프로그램 최적화를 피할 수있는 ABI에 대한 준수가 필요하지만 링크는 일반적으로 VM에서 연기되며 전체 프로그램 최적화 (.NET의 REIFIED 제네릭)의 혜택을 누릴 수 있습니다.

또한 위의 Paercebal의 고도로 높은 대답 (누군가가 그의 답변에 대한 내 의견을 계속 삭제하기 때문에)에 대한 몇 가지 문제를 해결하고 싶습니다.

코드 처리는 편집 시간에 수행됩니다 ...

따라서 템플릿 Metaprogramming은 프로그램을 컴파일 시간에 사용할 수있는 경우에만 작동합니다. 예를 들어 바닐라 C ++에서 경쟁적으로 수행되는 정규식 라이브러리를 작성하는 것은 불가능합니다 (런 타임 코드 생성이 불가능하기 때문입니다. 메타 프로 그램).

... 유형으로 플레이하는 것은 컴파일 타임에 수행됩니다 ... Java 또는 C#의 동등한 것은 글을 쓰는 것이 가장 고통스럽고, 컴파일 시간에 유형이 알려진 경우에도 런타임에 항상 느리게 진행됩니다.

C#에서는 참조 유형에만 해당되며 값 유형에 맞지 않습니다.

JIT 최적화에 관계없이 메모리에 직접 포인터 액세스 할 수있는 것은 아무것도 없습니다 ... 메모리에 인접한 데이터가 있으면 C ++ 포인터를 통해 액세스하면 (예 : Caesar에게 기한을 제공하자) Java/C#보다.

사람들이 관찰했습니다 SCIMARK2 벤치 마크에서 SOR 테스트에서 C ++를 치는 Java 포인터가 별명 관련 최적화를 방해하기 때문에 정확하게.

또한 .NET은 링크 후 동적으로 연결된 라이브러리에서 제네릭의 전문화를 유형한다는 점에 주목할 가치가있는 반면 C ++는 링크를 링크하기 전에 템플릿을 해결해야하기 때문에 할 수 없습니다. 그리고 분명히 제네릭이 템플릿보다 큰 장점은 이해할 수있는 오류 메시지입니다.

다른 사람들이 말한 것 외에도 .NET과 Java를 이해하면 메모리 할당이 더 좋습니다. 예를 들어 C ++가 할 수는 없지만 (기본적으로, 영리한 쓰레기 수집가를 사용하는 경우) 메모리가 조각화 될 때 메모리를 압축 할 수 있습니다.

많은 속도가 필요한 경우 JVM은 C ++ 구현을 호출하기 때문에 대부분의 OS 관련 제품에 대한 JVM이 얼마나 좋은지보다 Libs가 얼마나 좋은지에 대한 의문입니다. 쓰레기 수집은 메모리를 반으로 줄이지 만 더 멋진 STL 및 부스트 기능을 사용하면 동일한 효과가 있지만 버그 잠재력은 여러 번 발생합니다.

많은 클래스가있는 대형 프로젝트에서 C ++ 라이브러리와 많은 고급 기능을 사용하는 경우 JVM을 사용하는 것보다 느리게 증가 할 것입니다. 훨씬 더 많은 오류가 발생하기 쉬운 경우를 제외하고.

그러나 C ++의 이점은 자신을 최적화 할 수 있다는 것입니다. 그렇지 않으면 컴파일러/JVM이하는 일에 갇혀 있습니다. 자신의 컨테이너를 만들고 정렬 된 자체 메모리 관리를 작성하고 SIMD를 사용하고 여기저기서 어셈블리로 드롭으로 드롭으로 드롭으로 드롭이 대부분의 C ++ 컴파일러가 직접 수행 할 것보다 2x-4x 이상을 높일 수 있습니다. 일부 작업의 경우 16x-32x. 동일한 알고리즘을 사용하고 있습니다. 더 나은 알고리즘을 사용하고 병렬화되면 증가하는 것은 극적이며 때로는 일반적으로 사용되는 방법보다 수천 배 더 빠를 수 있습니다.

나는 몇 가지 다른 점에서 그것을 본다.

  1. 무한한 시간과 리소스가 주어지면 관리 또는 관리되지 않는 코드가 더 빨라질까요? 분명히, 대답은 관리되지 않는 코드가 항상이 측면에서 최소한 관리 코드를 묶을 수 있다는 것입니다. 최악의 경우와 같이 관리 된 코드 솔루션을 하드 코딩하는 것입니다.
  2. 한 언어로 프로그램을 가져 와서 다른 언어로 직접 번역하면 얼마나 악화 될까요? 아마도 많이 어느 두 언어. 대부분의 언어마다 최적화가 필요하며 Gotchas가 다릅니다. 미세 성능은 종종 이러한 세부 사항을 아는 데 많은 것입니다.
  3. 유한 한 시간과 리소스가 주어지면 두 언어 중 어느 것이 더 나은 결과를 얻을 수 있습니까? 관리되는 언어가 약간 느린 코드를 생성 할 수 있지만 (해당 언어를 위해 합리적으로 작성된 프로그램이 주어지면) 그 버전은 더 빨리 수행 될 가능성이 높아서 최적화에 더 많은 시간을 소비 할 수 있기 때문에 이것은 가장 흥미로운 질문입니다.

매우 짧은 답변 : 고정 된 예산이 주어지면 C ++ 응용 프로그램 (ROI 고려 사항)보다 더 나은 Java 응용 프로그램을 달성 할 수 있습니다. 또한 Java 플랫폼은 더 괜찮은 프로파일 러를 가지고있어 핫스팟을 더 빨리 정확하게 찾아 낼 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top