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 ++의 경우 0 이었습니다), 사실 템플릿 메타 프로그래밍과 함께 이것은 언급 할 가치가 있습니다. 하찮은...
편집 2011-06-10 : C ++에서 유형을 가지고 노는 것은 컴파일 타임에 수행됩니다. 즉, 비 제네릭 코드를 호출하는 제네릭 코드를 생성합니다 (예 : 문자열에서 유형 T로 일반 파서, 인식하는 유형 T에 대한 표준 라이브러리 API 호출, 사용자가 파서를 쉽게 확장 할 수 있도록하는 것은 매우 쉽고 효율적입니다. 반면 Java 또는 C #의 동등한 것은 작성하기가 힘들고 컴파일 시간에 유형이 알려진 경우에도 런타임에 항상 느리고 해결됩니다. 당신의 유일한 희망 은 JIT가 모든 것을 인라인하는 것입니다.
...
2011-09-20 편집 : Blitz ++ ( Homepage , Wikipedia ) 팀 은 그렇게했으며, 분명히 그들의 목표는 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 함수 HeapSetInformation ) 을 호출하여 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 #의 일부 코드는 40 바이트 접근자를 생성하며, 이는 JIT에 의해 인라인되지 않습니다. C ++ / CLI의 동일한 코드는 JIT에 의해 인라인되는 20 바이트 접근자를 생성합니다.
또 다른 예는 C # 컴파일러에 의해 생성 된 IL에서 여전히 언급되는 동안 C ++ 컴파일러에 의해 단순히 컴파일되는 임시 변수입니다. C ++ 정적 컴파일 최적화는 더 적은 코드를 생성하므로 더 적극적인 JIT 최적화를 다시 승인합니다.
그 이유는 C ++ / CLI 컴파일러가 C ++ 네이티브 컴파일러의 방대한 최적화 기술로부터 이익을 얻었 기 때문으로 추측되었습니다.
결론
저는 C ++을 좋아합니다.
그러나 내가 보는 한, C # 또는 Java가 모두 더 나은 선택입니다. C ++보다 빠르기 때문이 아니라 품질을 더하면 생산성이 높아지고 교육이 덜 필요하며 C ++보다 완전한 표준 라이브러리를 갖게되기 때문입니다. 그리고 대부분의 프로그램의 경우 속도 차이 (어떤면에서든)는 무시할 수있을 것입니다.
편집 (2011-06-06)
C # /. NET에 대한 나의 경험
저는 이제 거의 독점적 인 전문 C # 코딩을 5 개월 동안 받았습니다 (이미 C ++ 및 Java로 가득 찬 CV와 C ++ / CLI 터치에 추가됨).
나는 WinForms (Ahem ...)와 WCF (멋지다!), WPF (Cool !!!! 둘 다 XAML과 raw C #를 통해 놀았다. WPF는 스윙이 그것과 비교할 수 없다고 생각한다), C # 4.0으로 놀았다.
결론은 C ++보다 C # / Java에서 작동하는 코드를 생성하는 것이 더 쉽고 빠르지 만 C ++보다 C #에서 강력하고 안전하며 강력한 코드를 생성하는 것이 훨씬 더 어렵습니다 (자바에서는 더 어렵습니다). 이유는 많지만 다음과 같이 요약 할 수 있습니다.
- 제네릭 템플릿만큼 강력하지 않은 ( T로 문자열에서 효율적인 일반적인 구문 분석 방법을 (작성하려고), 또는 부스트의 효율적인 동등한 :: lexical_cast C #에서 문제를 이해하기 )
- RAII는 타의 추종을 불허합니다 ( GC는 여전히 누수 될 수 있으며 (예, 해당 문제를 처리해야했습니다). 메모리 만 처리합니다. C #조차도
using
올바른 Dispose 구현을 작성하는 것이 어렵 기 때문에 쉽고 강력하지 않습니다. )
- C #
readonly
및 Java는 final
유용으로 아무데도 C ++의const
( 가 내장 된 C ++의 기능입니다. 불변의 데이터가 흥미로운 솔루션입니다 중에도 엄청난 작업없이 C #에서 읽기 전용 복잡한 데이터 예를 들어 노드의 (나무를) 노출 할 수있는 방법은 없습니다 ,하지만 모든 것을 불변으로 만들 수있는 것은 아니기 때문에 충분하지 않습니다 .
따라서 C #은 작동하는 것을 원하는 한 유쾌한 언어로 남아 있지만 항상 안전하게 작동 하는 것을 원하는 순간에는 실망스러운 언어 입니다.
Java는 C #과 동일한 문제를 가지고 있기 때문에 훨씬 더 실망 스럽습니다. C #의 using
키워드에 상응하는 기능이 부족한 저의 매우 숙련 된 동료는 리소스가 올바르게 해제되었는지 확인하는 데 너무 많은 시간을 소비했지만 C ++에서는 (소멸자와 스마트 포인터 사용) 쉬웠습니다.
그래서 저는 C # / Java의 생산성 향상이 대부분의 코드에서 볼 수 있다고 생각합니다. 코드가 최대한 완벽해야하는 날까지. 그날, 당신은 고통을 알게 될 것입니다. (서버와 GUI 앱에서 요청한 내용을 믿지 못할 것입니다 ...).
서버 측 Java 및 C ++ 정보
건물 반대편에있는 서버 팀 (GUI 팀으로 돌아 가기 전에 2 년 동안 일했습니다)과 계속 연락했고 흥미로운 것을 배웠습니다.
지난 몇 년 동안 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 ++로 작성하기가 훨씬 쉽습니다]. "
- 허브 셔터는 에 // 빌드 / , 인용 안드레이 Alexandrescu의를
출처 :