에이. 오늘날 Java의 속도는 C ++과 어떻게 비교됩니까?
측정하기 어려움. 구현 속도의 주요 부분 인 메모리 할당자는 Java 및 C ++에서 매우 다른 알고리즘이라는 점에 주목할 가치가 있습니다. 콜렉터의 비 결정적 특성으로 인해 콜렉터의 상태를 확실하게 알 수 없기 때문에 C ++의 결정적 메모리 관리와 비교할 때 의미있는 성능 데이터를 얻는 것이 매우 어렵습니다. 이는 벤치 마크 작성이 매우 어렵다는 것을 의미합니다. 의미 적으로 비교할 수 있습니다. 일부 메모리 할당 패턴은 GC로 훨씬 빠르게 실행되고, 일부는 네이티브 할당기로 훨씬 빠르게 실행됩니다.
그러나 내가 말할 것은 모든 상황 에서 Java GC가 빠르게 실행되어야한다는 것 입니다. 그러나 기본 할당자는 더 적합한 할당기를 교체 할 수 있습니다. 나는 최근 C # 이 왜 내 컴퓨터에서 (0.45 ms)에서 동등한 것과 비교할 수 있는지에 대해 SO 에 대한 질문을했다.Dictionary
std::unordered_map
내 컴퓨터에서 10ms 동안 실행되었습니다. 그러나 할당 자와 워셔를 더 적절한 것으로 교체하기 만하면 실행 시간을 원래 런타임의 30 분의 30으로 내 컴퓨터에서 0.34ms로 줄였습니다. Java를 사용하여 이러한 종류의 사용자 정의 최적화를 수행하기를 결코 기대할 수 없습니다. 이것이 실제로 차이를 만들 수있는 훌륭한 예는 스레딩입니다. TBB와 같은 기본 스레드 라이브러리는 많은 스레드에서 많은 할당을 처리 할 때 기존 할당 자보다 훨씬 빠른 스레드 캐싱 할당자를 제공합니다.
이제 많은 사람들이 JIT 개선에 대해 이야기하고 JIT가 더 많은 정보를 얻는 방법에 대해 이야기 할 것입니다. 물론입니다. 그러나 컴파일러는 최종 프로그램의 런타임 관점에서 비교할 때 무한한 시간과 공간이 있기 때문에 C ++ 컴파일러가 가져올 수있는 것과 여전히 가깝지 않습니다. JIT가 프로그램을 최적화하는 가장 좋은 방법에 대해 생각하는 모든 사이클과 모든 바이트는 프로그램이 실행하지 않고 자체 메모리 요구에 사용할 수없는 사이클입니다.
또한, 특히 이스케이프 분석과 같은 경우 컴파일러 및 JIT 최적화가 특정 최적화를 입증 할 수없는 경우가 있습니다. 값이 스택에로 C ++에서는 다음 어쨌든 , 컴파일러를 수행 할 필요가 없습니다. 또한 연속 메모리와 같은 간단한 것들이 있습니다. C ++로 배열을 할당하면 연속 된 단일 배열을 할당합니다. Java로 배열을 할당하면 배열이 아무 데나 가리킬 수있는 포인터로 채워지기 때문에 배열이 전혀 연속적이지 않습니다. 이는 이중 간접 메모리에 대한 메모리 및 시간 오버 헤드 일뿐만 아니라 캐시 오버 헤드이기도합니다. 이런 종류의 일은 Java의 언어 의미가 단순히 동등한 C ++ 코드보다 느려 야한다는 것을 강제하는 곳입니다.
궁극적으로 제 개인적인 경험은 Java가 평균적으로 C ++ 속도의 절반 정도가 될 수 있다는 것입니다. 그러나 기본적으로 다른 알고리즘이 포함되어 있기 때문에 매우 포괄적 인 벤치 마크 제품군 없이는 성능 설명을 백업 할 수있는 방법이 없습니다.
비. Java를 사용하여 최신 AAA 타이틀을 만들 수 있습니까?
나는 여기서 당신이 기회가 아니라 "게임"을 의미한다고 가정합니다. 먼저, 거의 모든 기존 라이브러리 및 인프라가 C ++을 대상으로하는 것처럼 모든 것을 처음부터 작성해야합니다. 그 자체로는 불가능하지는 않지만 실현 불가능한 방향으로 확실히 기여할 수 있습니다. 둘째, C ++ 엔진조차도 기존 콘솔의 작은 메모리 제약에 거의 맞지 않습니다 (해당 콘솔에 JVM이 존재하고 PC 게이머는 자신의 메모리에 조금 더 기대할 경우). C ++에서 퍼포먼스 AAA 게임을 만드는 것은 충분히 어렵지만 Java로 어떻게 달성 할 수 있는지 알 수 없습니다. 컴파일되지 않은 언어로 상당한 시간을 소비 한 AAA 게임을 만든 사람은 없습니다. 그 이상으로 오류가 발생하기 쉽습니다. 예를 들어 GPU 리소스와 Java를 다룰 때는 결정 론적 파괴가 필수적입니다.
씨. Java가 C ++보다 느린 영역은 무엇입니까? (예 : 숫자 처리, 그래픽 또는 그 밖의 모든 것)
나는 확실히 만능에 갈 것이다. 모든 Java 객체의 강제 참조 특성은 Java가 C ++보다 훨씬 더 많은 간접 참조와 참조를 가지고 있음을 의미합니다. C ++ 컴파일러가 일정한 시간에 멤버 변수를 찾을 수있는 경우 Java 런타임은 다른 포인터를 따라야합니다. 액세스가 많을수록 속도가 느려지고 JIT가 할 수있는 일은 없습니다.
C ++이 거의 즉시 메모리 조각을 비우고 재사용 할 수있는 곳에서는 Java에서 수집을 기다려야하며 조각이 캐시에서 떨어지지 않았으며 본질적으로 더 많은 메모리가 필요하면 캐시 및 페이징 성능이 저하되기를 바랍니다. 그런 다음 복싱 및 언 박싱과 같은 의미를 살펴보십시오. Java에서 int를 참조하려면 동적으로 할당해야합니다. 그것은 C ++ 의미와 비교할 때 고유 한 낭비입니다.
그런 다음 제네릭 문제가 있습니다. Java에서는 런타임 상속을 통해서만 일반 객체에서 작업 할 수 있습니다. C ++에서 템플릿은 문자 그대로 오버 헤드가 없으며 Java와는 비교할 수 없습니다. 이것은 Java의 모든 일반 코드가 본질적으로 C ++의 일반 코드보다 느리다는 것을 의미합니다.
그리고 당신은 정의되지 않은 행동에 온다. 프로그램에 UB가 표시되면 누구나 싫어하고, 존재하지 않기를 바랍니다. 그러나 UB는 근본적으로 Java에는 존재할 수없는 최적화를 가능하게합니다. UB를 기반으로 한 최적화를 설명하는 이 게시물을 살펴보십시오 . 동작을 정의하지 않으면 구현에서 더 많은 최적화를 수행하고 C ++에서 정의되지 않았지만 Java로 정의 된 조건을 확인하는 데 필요한 코드를 줄일 수 있습니다.
기본적으로 Java의 의미는 C ++보다 느린 언어임을 나타냅니다.
Java는 이제 컴파일 된 언어 또는 해석 된 언어로 간주됩니까?
이 두 그룹 중 어느 것도 적합하지 않습니다. 나는 매니지드가 실제로는 별도의 카테고리라고 말하고 싶지만 컴파일 된 언어보다 해석 된 언어와 더 비슷하다고 말하고 싶습니다. 더 중요한 것은 두 가지 주요 관리 시스템 인 JVM과 CLR 만 있고 "관리"라고 말하면 충분히 명시 적입니다.
초기부터 해결 된 Java의 주요 단점은 무엇입니까?
내가 아는 유일한 것은 자동 권투 및 언 박싱입니다. 제네릭은 몇 가지 문제를 해결 하지만 많은 문제와는 거리가 멀다.
아직 해결되지 않은 Java의 주요 단점은 무엇입니까?
그들의 제네릭은 매우 약합니다. C #의 제네릭은 상당히 강력하지만 물론 템플릿도 아닙니다. 결정 론적 파괴는 또 다른 주요 결점입니다. 모든 형태의 람다 / 클로저도 중요한 문제입니다. Java에서 기능적 API를 잊어 버릴 수 있습니다. 물론 성능이 필요한 영역에는 항상 성능 문제가 있습니다.