자바는 정말 느리다?


180

자바는 속도가 느리다는 명성을 가지고있다 .

  • 자바는 정말 느리다?
  • 그렇다면 왜 그렇습니까? 병목 현상은 어디에 있습니까? 비효율적 인 JVM 때문입니까? 쓰레기 수거? JNI 랩 C 코드 대신 순수한 바이트 코드 라이브러리? 다른 많은 언어들에도 이러한 기능이 있지만 속도 저하에 대한 명성은 없습니다.

35
사람들은 너무 긴장해서 ... 이것이 주관적 일 수있는 방법을 보거나 논쟁 적이 지 않습니다. "버블 정렬이 느린 이유"와 같은 질문이 같은 결과를 얻을 수 있을지 궁금합니다. 나는 기술적 인 질문을하고 기술적 인 답변을 원했지만 주관적이고 논쟁적인 질문을 끝내는 것은 어리 석습니다.
Stefano Borini

1
필자는 대부분의 주요 의견을 읽었으며 C # GUI 기반 데스크톱 응용 프로그램이 최신 응용 프로그램을 포함한 Java GUI 기반 데스크톱 응용 프로그램보다 훨씬 빠르게 실행된다는 놀라운 사실을 다루지 않는 것 같습니다.
BobTurbo

3
.net webforms, .net MVC, PHP, Rails, Django 및 Java (Spring (내가 들었다)는 제외)의 다양한 모든 것을 처리 한 클라이언트 측 웹 개발자로서 나는 성능 / 아키텍처가 좋지 않을 것으로 기대합니다. Java 팀이 구축 한 백엔드에서 실제 문제는 벤치 마크가 아니라 평범한 자바 개발자가 있다는 문제입니다. 그것은 언어의 잘못이 아닙니다. 실제로 기술을 연마하고 Java 이외의 언어를 배우는 Java 개발자의 잘못이 아닙니다. 그러나 일반적으로 Sun, 인증서, 90 년대 및 IT 산업의 결함 일 수 있습니다.
Erik Reppen

답변:


236

현대 Java는 여전히 메모리 호그이지만 가장 빠른 언어 중 하나입니다. Java VM을 시작하는 데 오랜 시간이 걸리기 때문에 느리게 명성을 얻었습니다.

여전히 Java가 느리다고 생각 되면 벤치 마크 게임 결과를 참조하십시오 . 미리 컴파일 된 언어 (C, Fortran 등)로 작성된 엄격하게 최적화 된 코드가 이길 수 있습니다. 그러나 Java는 PHP, Ruby, Python 등보다 10 배 이상 빠를 수 있습니다. 일반적인 컴파일 된 언어 (표준 라이브러리를 사용하는 경우)를 능가 할 수있는 특정 영역이 있습니다.

"느린"Java 응용 프로그램에 대한 변명의 여지가 없습니다. 개발자와 레거시 코드 / 라이브러리는 언어보다 훨씬 더 많은 책임이 있습니다. 또한 '기업'을 비난합니다.

"자바는 느리다"군중에 공평하게, 여기에는 여전히 느리다 (2013 년 업데이트).

  • 라이브러리는 종종 성능이 아니라 "정확성"및 가독성을 위해 작성됩니다. 제 생각에는 이것이 자바가 여전히 평판이 좋지 않은 주된 이유, 특히 서버 측입니다. 이것은 문자열 문제를 기하 급수적으로 악화시킵니다. 몇 가지 간단한 실수가 일반적입니다. 객체는 기본 요소 대신 자주 사용되므로 성능이 떨어지고 메모리 사용이 증가합니다. 표준 라이브러리를 포함한 많은 Java 라이브러리는 변경 가능하거나 간단한 형식 (char [] 또는 StringBuffer)을 재사용하지 않고 문자열을 자주 만듭니다. 속도가 느리고 나중에 수거 할 쓰레기가 많이 발생합니다. 이 문제를 해결하기 위해 개발자는 가능한 경우 기본 컬렉션과 특히 Javalution의 라이브러리를 사용하는 것이 좋습니다.

  • 문자열 연산이 약간 느립니다. Java는 불변의 UTF-16 인코딩 문자열 객체를 사용합니다. 즉, ASCII (C, C ++)보다 더 많은 메모리, 더 많은 메모리 액세스가 필요하며 일부 작업이 더 복잡합니다. 당시에는 이식성 에 대한 올바른 결정 이었지만 성능 비용이 약간 듭니다. UTF-8 은 이제 더 나은 선택처럼 보입니다.

  • 범위 검사로 인해 C에 비해 배열 액세스가 약간 느립니다 . 벌금은 커졌지 만 이제는 작습니다 (Java 7은 많은 중복 범위 검사를 최적화합니다).

  • 임의 메모리 액세스가 부족하면 일부 I / O 및 비트 수준 처리 속도가 느려질 수 있습니다 (예 : 압축 / 압축 해제). 이것은 현재 대부분의 고급 언어의 안전 기능입니다.

  • Java는 C보다 많은 메모리를 사용하며 응용 프로그램이 메모리 바운드 또는 메모리 대역폭 바운드 (캐싱 등) 인 경우 속도가 느려집니다. 단점은 할당 / 할당 해제 속도가 매우 빠르다는 것입니다 (최적화 됨). 이것은 현재 대부분의 고급 언어의 기능이며, 명시 적 메모리 할당이 아닌 객체 및 GC 사용으로 인해 발생합니다 . 잘못된 도서관 결정.

  • 스트림 기반 I / O는 (IMO, 잘못된 선택) 때문에 각 스트림 액세스에서 동기화가 필요하기 때문에 느립니다 . NIO는 이것을 고쳤 지만 사용하기가 쉽지 않습니다 . 한 번에 요소 대신 배열에 대한 읽기 / 쓰기를 수행하여이 문제를 해결할 수 있습니다.

  • Java는 C와 동일한 저수준 기능을 제공하지 않으므로 더러운 인라인 어셈블러 트릭을 사용하여 일부 작업을 더 빠르게 수행 할 수 없습니다. 이것은 이식성을 제공하며 현재 대부분의 고급 언어 기능입니다.

  • Java 애플리케이션이 매우 오래된 JVM 버전과 연관되어있는 것이 일반적입니다. 특히 서버 측. 이 오래된 JVM은 최신 버전에 비해 매우 비효율적 일 수 있습니다.

결국 Java는 일부 성능을 희생시키면서 보안과 이식성을 제공하고 실제로는 까다로운 작업을 위해 설계되었습니다. 속도 저하에 대한 명성의 대부분은 더 이상 가치가 없습니다.


그러나 Java가 대부분의 다른 언어보다 빠른 곳은 여러 곳 입니다.

  • 메모리 할당 및 할당 해제는 빠르고 저렴합니다. 캐시 된 것을 재사용하는 것보다 새로운 다중 kB 배열을 할당하는 것이 20 % 더 빠릅니다 (또는 그 이상!).

  • 객체 인스턴스화 및 객체 지향 기능은 처음부터 설계되었으므로 사용하기가 매우 빠릅니다 (경우에 따라 C ++보다 빠름). 이것은 부분적으로 명시적인 할당이 아닌 좋은 GC에서 비롯된 것입니다 (많은 작은 객체 할당에 더 친숙합니다). 사용자 정의 메모리 관리를 롤링하고 malloc을 효율적으로 수행하여 C를 코딩 할 수는 있지만 쉽지는 않습니다.

  • 메소드 호출은 기본적으로 무료이며 경우에 따라 대형 메소드 코드보다 빠릅니다. 핫스팟 컴파일러 최적화 메소드 호출에 실행 정보를 사용하여 매우 효율적인 인라인있다. 추가 실행 정보를 사용하면 때때로 선행 컴파일러보다 성능이 우수하고 수동 인라이닝을 수행 할 수 있습니다. 컴파일러가 인라인하지 않기로 결정한 경우 메소드 호출에 약간의 성능 저하가 발생하는 C / C ++와 비교하십시오.

  • 동기화 및 멀티 스레딩은 쉽고 효율적입니다. Java는 처음부터 스레드를 인식하도록 설계되었습니다. 최신 컴퓨터에는 일반적으로 여러 코어가 있으며 스레딩이 언어에 내장되어 있으므로 매우 쉽게 활용할 수 있습니다. 기본적으로 표준 단일 스레드 C 코드에 비해 추가 100 % ~ 300 % 속도 향상. 그렇습니다. 신중하게 작성된 C 스레딩과 라이브러리는 이것을 능가 할 수 있지만 프로그래머에게는 많은 추가 작업이 필요합니다.

  • 문자열에는 길이가 포함됩니다. 일부 작업이 더 빠릅니다. 이것은 널로 구분 된 문자열 (C에서 공통)을 사용하여 이깁니다. Java 7에서 사람들은 String.subString () 최적화를 사용했습니다. 사람들이 어리석게 사용하고 메모리 누수가 발생했기 때문입니다.

  • 어레이 복사가 고도로 최적화되었습니다. 최신 버전에서 Java는 System.arraycopy에 대해 수동 조정 어셈블러를 사용합니다. 결과는 arraycopy / memcopy-heavy 작업에서 내 코드가 C에서 동등한 마진으로 동등한 것을 보았습니다.

  • JIT 컴파일러는 L1 / L2 캐시를 사용하는 것이 현명 합니다 . 미리 컴파일 된 프로그램은 코드를 실시간으로 실행중인 특정 CPU 및 시스템에 맞게 조정할 수 없습니다. JIT는 이런 방식으로 매우 효율적인 루프 변환을 제공합니다.

몇 가지 다른 역사적 사실이 "자바는 느리다"라는 평판에 기여했습니다.

  • JIT 컴파일 (Java 1.2 / 1.3) 이전에는 언어 만 해석되고 컴파일되지 않았으므로 매우 느 렸습니다.
  • JIT 컴파일이 효율적이되기까지 시간이 걸렸습니다 (각 버전에서 크게 개선됨)
  • 클래스 로딩은 수년에 걸쳐 훨씬 더 효율적이되었습니다. 예전에는 비효율적이고 속도가 느 렸습니다.
  • Swing 및 UI 코드는 기본 그래픽 하드웨어를 잘 사용하지 않았습니다.
  • 스윙은 끔찍합니다. 나는 왜 Java가 데스크탑에 붙 잡히지 않았는지 AWT와 Swing을 비난합니다.
  • 라이브러리 클래스에서 많은 동기화 사용; 동기화되지 않은 버전을 사용할 수 있습니다
  • 애플릿 은 네트워크를 통해 전체 JAR 을 전송하고 부팅 할 VM을로드 하기 때문에 영원히로드 됩니다.
  • 성능 저하가 심할 때 사용되는 동기화 (각 Java 버전에 최적화되어 있음) 그러나 반사는 여전히 비용이 많이 든다.

49
Object instantiation and object-oriented features are blazing fast to use (faster than C++ in many cases) because they're designed in from the beginning.그리고 Collections are fast. Standard Java beats standard C/C++ in this area, even for most optimized C code.여기에 링크 된 증거에 의해 지원되지 않는 야생 주장이다.
Sjoerd

8
@Sjoerd-주장은 거칠지 않습니다. 나에게 명백하며 C / C ++과 Java의 기본 메모리 시스템 아키텍처의 차이점을 이해하는 사람이라면 누구나 이해할 수 있습니다. 사용 가능한 목록, 메모리 풀 등과 같은 자체 메모리 핸들러를 작성하거나이를 구현하는 라이브러리를 사용하는 경우 훨씬 더 잘 수행 있습니다 .
렉스 커

15
@Rex Kerr-할당을 위해 스택을 사용할 수 있다면 왜 메모리 핸들러를 사용합니까?! 힙 메모리 할당과 객체 인스턴스화를 혼동하고 있습니다.
Sjoerd

20
@Rex Kerr-기본적으로 Java의 모든 것이 힙에 메모리 할당을 포함하고 Java의 힙에 대한 Java 할당이 C ++보다 빠르기 때문에 Java의 모든 것이 더 빠르다고 주장합니다. C ++에서는 많은 경우 힙에 메모리를 할당하지 않고도 할 수 있습니다!
Sjoerd

10
@Sjoerd- Java의 모든 것이 더 빠르다고 어디서 말했 습니까? 내가 한 말을 읽어보세요. 나는 내가 의미하는 바를 말했고, 당신이 마지막으로 언급 한 모든 것을 이미 언급했습니다.
렉스 커

49

처음에는 Java가 특별히 빠르지는 않았지만 지나치게 느리지 않았습니다. 요즘 Java는 매우 빠릅니다. 내가 말한 사람들로부터 Java가 느리다는 인상에 대해 두 가지가 있습니다.

  1. VM 시작 시간이 느립니다. 초기 Java 구현은 기본 애플리케이션과 비교하여 필수 라이브러리 및 애플리케이션을 시작하고로드하는 데 오랜 시간이 걸렸습니다.

  2. 느린 UI. 초기 스윙 은 느렸다. 대부분의 Windows 사용자가 기본 Metal L & F를 못 찾게하는 데 도움이되지 않았을 것입니다.

위의 점을 감안할 때 사람들이 '자바는 느리다'라는 인상을 받았다는 것은 놀라운 일이 아닙니다.

기본 응용 프로그램 또는 Visual Basic 개발에 익숙한 사용자 또는 개발자 응용 두 가지 점이 응용 프로그램에서 가장 눈에 띄는 부분이며 응용 프로그램에 대한 첫 인상입니다 (GUI 이외의 응용 프로그램이 아닌 한) 경우에만 적용됩니다.).

코드 실행 및 시작 시간이 전혀 연결되지 않았더라도 응용 프로그램을 시작하는 데 8 초가 걸리는 즉시 이전의 Visual Basic 응용 프로그램과 비교할 때 "코드를 매우 빠르게 실행"한다고 사용자에게 확신시키지 않습니다.

첫인상을 망치는 것은 소문과 신화를 시작하는 좋은 방법입니다. 그리고 소문과 신화는 죽이기 어렵다.

요컨대, Java는 느리지 않습니다. "자바는 느린 태도"를 가진 사람들은 10 년 전의 자바에 대한 첫인상을 기반으로합니다.


3
Java는 몇 년 전에 매우 느 렸지만 최근 벤치 마크 테스트에서 C / C ++만큼 빠르게 실행되고 일부 상황에서는 더 빠르게 실행됩니다.
ChadNC

23
Macbook에서 OSX 10.6의 Java 앱은 Objective-C로 작성된 앱보다 훨씬 느리게 시작됩니다. 빠른 시작 시간에 대한 증거는 무엇입니까?
Zan Lynx

2
감압은 절대적으로 성능 문제가 아닙니다. 1992 년에 내 컴퓨터는 프로그램을 시작할 때 실행 파일의 압축을 풀어 하드 드라이브에서 더 긴 파일을로드하는 것보다 성능이 향상되었습니다. CPU와 하드 드라이브의 불균형은 그 사이에 엄청나게 커졌습니다. 그러나 rt.jar에 zip 아카이브 형식을 사용하는 데 문제가 있으며 (이유는? !!!) 포함 된 클래스 파일이 연결되어 있지 않습니다 (너트 !!).
Tom Hawtin-tackline

5
@Zan : Mac OS X 용 JVM은 Apple에서 작성했습니다. 썬은 지원하는 플랫폼 (Windows, Linux 및 Solaris)에서 시작 시간을 단축하기 위해 상당한 시간을 투자했지만 Mac OS x에서는 해당 포트를 유지하지 않기 때문에 시작할 수 없었습니다. Mac이 모든 최적화를 Mac OS X에 적용 / 적용 / 포팅 할 수 없었을 수도 있습니다.
Joachim Sauer

1
나는 자바가 느리다고 생각하지 않습니다 (나는 게임을 만드는 게임 제작자를 알고 있습니다). UI 때문에 나쁘다. 내가 본 단일 "일반"Java 앱이 아니고 괜찮은 수준으로 작동하는 UI가 있습니다.
RCIX

40

Java가 느리지 않다는 의견이 가득 찬 페이지를 읽은 후에는 다른 의견으로 대답해야합니다.

언어의 속도 저하는 '빠른'기대치에 따라 크게 달라집니다. C #이 빠르다고 생각하면 Java도 빠릅니다. 문제 도메인이 데이터베이스 또는 반 실시간 처리와 관련이 있으면 Java도 충분히 빠릅니다. 더 많은 하드웨어를 추가하여 응용 프로그램을 확장하고 싶다면 Java가 가장 빠를 것입니다. 5-10의 스케일에서 상수 팩터 속도가 그다지 가치가 없다고 생각하면 Java를 빠르게 고려할 수 있습니다.

큰 데이터 세트에서 숫자 계산을 수행하거나 CPU 자원이 제한되어 있고 5-10의 규모로 지속적인 속도 향상이 큰 실행 환경에 바인딩 된 경우. 0.5 배속이라도 계산이 완료되는 데 500 시간이 단축 될 수 있습니다. 이 경우 Java는 마지막 성능을 얻을 수 없으며 Java를 느리게 생각할 수 있습니다.


2
예를 들어, C ++은 디버그하기가 어렵고 다리 전체를 날려 버릴 수 있다는 다른 명성을 가지고 있지만 C ++이 느리다는 소식은 거의 들지 않았습니다. Java에 대해 들었습니다.
Stefano Borini 2019

33

두 가지 다른 질문을하는 것 같습니다.

  1. Java는 정말로 느리며 왜 그렇다면 그 이유는 무엇입니까?
  2. 많은 대안보다 빠르지 만 Java가 왜 느리게 인식됩니까?

이 중 첫 번째는 "로프가 얼마나 오래 걸리는가"라는 질문입니다. "느린"의 정의로 귀결됩니다. 순수한 인터프리터에 비해 Java는 매우 빠릅니다. 어떤 종류의 바이트 코드로 (일반적으로) 컴파일 된 다음 기계 코드 (예 : C # 또는 .NET의 다른 것)로 동적으로 컴파일 된 다른 언어와 비교할 때 Java는 거의 비슷한 수준입니다. 일반적으로 순수한 기계 코드로 컴파일되고 언어 최적화 프로그램 (예 : C, C ++, Fortran, Ada)을 개선하는 것 외에는 아무 일도하지 않는 사람들로 구성된 팀과 비교할 때 Java는 몇 가지 일을 잘 하지만 전반적으로 잘 수행합니다. 적어도 다소 느린 경향이 있습니다.

이것의 대부분은 주로 구현과 관련이 있습니다. 기본적으로 동적 / JIT 컴파일러가 실행되는 동안 사용자가 기다리고 있다는 사실에 기인합니다. 따라서 시작하는 데 꽤 오랜 시간 동안 실행되는 프로그램이 없다면 컴파일러가 어려운 최적화에 많은 시간을 소비하게 만드는 것은 정당화하기 어렵습니다. 따라서 대부분의 Java (및 C # 등) 컴파일러는 실제로 어려운 최적화에 많은 노력을 기울이지 않습니다. 많은 경우에, 최적화가 적용되는 위치보다 수행되는 최적화가 적습니다. 많은 최적화 문제는 NP가 완료되었으므로 문제의 크기가 커질수록 시간이 빠르게 증가합니다. 이유 내에서 시간을 유지하는 한 가지 방법은 한 번에 하나의 함수와 같은 것에 만 최적화를 적용하는 것입니다. 개발자 만 컴파일러를 기다리는 경우 훨씬 더 오래 걸릴 수 있고 프로그램의 훨씬 더 큰 청크에 동일한 최적화를 적용 할 수 있습니다. 마찬가지로 일부 최적화 코드는 매우 털이 많기 때문에 상당히 클 수 있습니다. 다시 말하지만 사용자는 해당 코드가로드되는 동안 대기하고 있기 때문에 (그리고 JVM 시작 시간이 전체 시간에서 중요한 요소 인 경우가 많음) 구현시 한 장소에서 절약 된 시간과 다른 장소에서 손실되는 시간의 균형을 유지해야합니다. 털이 최적화의 이점을 누리면 JVM을 작게 유지하는 것이 일반적으로 더 유리합니다.

두 번째 문제는 Java를 사용하면 "모든 크기에 맞는"종류의 솔루션을 어느 정도 얻을 수 있다는 것입니다. 예를 들어, 많은 Java 개발자에게 Swing은 기본적으로 유일한 사용 가능한 윈도우 라이브러리입니다. C ++과 같은 것에는 문자 그대로 수십 개의 윈도우 라이브러리, 응용 프로그램 프레임 워크 등이 있으며, 각각 사용 편의성 대 빠른 실행, 일관된 모양과 느낌, 기본 모양과 느낌 등의 고유 한 절충안이 있습니다. 유일한 고집 포인트는 일부 (예 : Qt)가 (적어도 상업적인 용도로는) 상당히 비쌀 수 있다는 것입니다.

셋째, C ++로 작성된 많은 코드 (그리고 C도 훨씬 더)는 단순히 더 오래되고 더 성숙합니다. 코드 최적화에 여분의 시간을 소비하는 것이 정상적인 예상되는 동작이었을 때 수십 년 전에 작성된 핵심 루틴이 많이 포함되어 있습니다. 그것은 종종 더 작고 빠른 코드에 실질적인 이점이 있습니다. C ++ (또는 C)는 코드가 작고 빠르다는 크레딧을 얻지 만 실제로 개발자의 제품이자 코드 작성 시간의 제약 조건입니다. 어느 정도까지는 사람들이 속도를 걱정할 때 종종 C ++을 선택합니다. 그들은 시간과 노력을 추가로 최적화하고 새로운 세대의 빠른 C ++ 코드를 작성했습니다.

요약하자면, 일반적인 Java 구현은 최대한의 최적화 문제를 야기합니다. 설상가상으로 Java가 보이는 곳에서는 윈도우 툴킷 및 JVM 시작 시간과 같은 것이 언어 자체의 실행 속도보다 더 큰 역할을합니다. 많은 경우에 C와 C ++는 또한 최적화에서 더 열심히 노력한 결과물에 대한 신뢰를 얻습니다.

두 번째 질문에 관해서는, 나는 그것이 직장에서의 인간 본성의 문제라고 생각합니다. 몇몇 열광 자들은 자바가 맹목적으로 빠르다는 주장을 다소 부풀렸다. 누군가 그것을 시도해보고 사소한 프로그램조차 시작하는 데 몇 초가 걸리고 실행되면 느리고 서투른 느낌이 든다는 것을 알았습니다. JVM의 시작 시간이며, 처음 시도 할 때 코드가 아직 컴파일되지 않았다는 사실을 인식하기 위해 사물을 분석하는 사람은 거의 없을 것입니다. 기다리는 동안 컴파일되는 것도 있습니다. 더 나쁜 것은, 충분히 빠르게 작동하더라도 모양과 느낌은 대부분의 사용자에게는 일반적으로 이질적이고 어색해 보일 것입니다.

이들을 함께 추가하면 Java가 느리고, 추악하고 어색하다는 상당히 간단하고 자연스러운 반응이 나타납니다. 이 과민 반응하는 경향이 그리고이라고 생각 결론이 빨리 정말 말 과대 광고를 감안할 때 끔찍 대신 (정확한)의 느린 "약간 느리게, 그 대부분에서 특정 상황." 이것은 일반적으로 언어로 처음 몇 개의 프로그램을 작성하는 개발자에게는 최악입니다. 대부분의 언어로 "hello world"프로그램을 실행하면 즉각적으로 나타나지만 Java에서는 JVM이 시작될 때 쉽게 인식 할 수있는 일시 정지가 있습니다. 타이트한 루프에서 훨씬 느리게 실행되는 순수한 인터프리터조차도로드와 비트가 조금 더 빨리 실행될 수 있기 때문에 이와 같은 코드에서는 여전히 더 빨리 나타납니다.


16

자바의 초기 (1990 년대 중반에서 후반까지)의 오래된 정보입니다. Java의 모든 주요 버전은 이전 버전에 비해 상당한 속도 향상을 가져 왔습니다. Oracle이 Java의 Java 7 용 JVM과 JRockit을 합병 한이 추세는 계속 될 것으로 보입니다.

다른 많은 인기있는 현대 언어 (Python, Ruby, PHP)와 비교할 때 Java는 대부분의 용도에서 실제로 훨씬 빠릅니다. C 또는 C ++과는 일치하지 않지만 많은 작업에서 충분히 가깝습니다. 실제 성능 문제는 사용하는 메모리 양에 관한 것입니다.


14

"긴 시작 시간"의 주요 원인은 동적 연결입니다. Java 애플리케이션은 컴파일 된 클래스로 구성됩니다. 각 클래스는 name으로 다른 클래스 (인수 유형, 메소드 호출 ...)를 참조 합니다. JVM은 시작시 해당 이름을 검사하고 일치시켜야합니다. 주어진 시간에 필요한 부분 만 수행하면서 점진적으로 수행하지만 여전히해야 할 일입니다.

C 응용 프로그램에서 해당 연결 단계는 컴파일이 끝날 때 발생합니다. 특히 큰 응용 프로그램의 경우 속도가 느리지 만 개발자 만 볼 수 있습니다. 링크하면 OS가 단순히 "있는 그대로"RAM에로드해야하는 실행 파일이 생성됩니다.

Java에서, 링크는 애플리케이션이 실행될 때마다 발생합니다. 따라서 시작 시간이 길다.

캐싱 기술을 포함하여 다양한 최적화가 적용되었으며 컴퓨터가 더 빨라지고 (응용 프로그램이 "더 크게"얻을수록 "더 빠르다") 문제의 중요성이 최근에 크게 줄었습니다. 그러나 오래된 편견이 남아 있습니다.

나중에 성능에 관해서는 배열 액세스 (주로 해시 함수 및 기타 암호화 알고리즘)를 사용한 소형 계산에 대한 내 벤치 마크는 일반적으로 최적화 된 C 코드가 Java 코드보다 약 3 배 빠릅니다. 때로는 C가 Java보다 30 % 빠르며, 구현 된 알고리즘에 따라 C가 4 배 빠를 수도 있습니다. 프로세서가 제공하는 64x64-> 128 곱셈 opcode로 인해 "C"코드가 실제로 큰 정수 산술을 위해 어셈블리되었을 때 10x 요소를 보았지만 가장 긴 정수 유형이 64 비트이기 때문에 Java를 사용할 수 없습니다 long. 이것은 엣지 케이스입니다. 실제 조건에서 I / O 및 메모리 대역폭 고려 사항으로 인해 C 코드 가 Java보다 실제로 3 배 더 빠릅니다.


흠 ... 요즘 대부분의 C 라이브러리가 동적으로 링크되었다고 생각했습니다. 아니면 다른 말을하고 있습니까?
Sean McMillan 2016 년

4
@Sean : "외부 심볼"에 대해 C에 대한 동적 링크가 발생합니다. 하나의 DLL에서 사용되고 다른 DLL에서 정의 된 함수입니다. 일반적인 C 응용 프로그램은 12 개의 DLL을 사용합니다. Java 동적 링크는 모든 클래스의 모든 메소드에 대해 발생합니다 . 표준 Java 애플리케이션 (표준 라이브러리 포함) 에는 수천 가지 가 있습니다. C 세계에서 대부분의 연결 (DLL 경계를 넘지 않는 모든 링크)은 컴파일 타임에 해결되며, 실행 시간에는 여전히 적은 비율 만 남아 있습니다.
Thomas Pornin 2016 년

14

Java는 특히 양적 작업의 경우 속도가 느립니다.

최적화 된 멀티 스레드 ATLAS 라이브러리 와 함께 R , Python 및 C / C ++ 조합을 사용합니다 . 이러한 각 언어에서 약 4 초 안에 3000 x 3000 행렬의 복식 행렬을 곱할 수 있습니다. Java에서 Colt 및 Parallel Colt를 사용하면 동일한 작업에 185 초가 걸립니다! 이러한 자바 라이브러리가 본질적으로 평행 함에도 불구하고 놀랍습니다.

따라서 순수한 Java는 정량 작업에 적합하지 않습니다. Jblas는 ATLAS를 사용하므로 Java를위한 최고의 선형 대수 라이브러리 인 것 같습니다.

내 컴퓨터는 RAM이 3GB 인 HP Core 2 Duo 입니다. 64 비트 Ubuntu 10.04 (Lucid Lynx)를 사용합니다.


앞서 언급 한 의견에서 JAMA를 사용하여 동일한 행렬 곱셈 연산을 수행했으며 약 50 초가 걸렸습니다. 다른 언어에 비해 여전히 느립니다.
Hamaad Shah

7
JNI를 통해 호출 된 라이브러리에서 곱셈을 수행 할 때 Java가 걸린 시간 C / C ++에서 할 수있는 모든 것을 JNI로 수행 할 수 있고 (수백 백만 노초 추가) 마진은 상대적으로 작습니다. R 및 Python 행렬 곱셈이 R 또는 Python으로 작성되지 않았으며 해당 언어에서 호출 된 것 같습니다.
피터 로리

2
호기심으로 코드에 핫스팟이 있는지 식별하기 위해 프로파일 링을 수행 했습니까 (유형 변환 / 오토 박싱)?
Thorbjørn Ravn Andersen 님이

10

대부분의 사람들과의 상호 작용 경험 Java 느립니다. 애플릿이 나오기 전에 브라우저에서 커피 컵이 돌아가는 것을 보았습니다. JVM을 가동시키고 애플릿 바이너리를 다운로드하는 데 시간이 걸리며 이는 사용자 경험에 눈에 띄는 방식으로 영향을 미칩니다.

느린 JVM 스핀 업 및 애플릿 다운로드 시간이 눈에 띄게 Java 커피 컵으로 브랜드화되어 사람들이 대기를 Java와 연관시키는 데 도움이되지 않습니다. 때 플래시가 로드에 시간이 오래 걸리는 사람들이 전체 플래시 기술을 비난하지 않는다, 그래서 "로드"메시지의 브랜드는 플래시 개발자에 의해 지정됩니다.

이 모든 것은 서버에서의 Java 성능과는 관련이 없으며 Java가 브라우저 외부에서 사용되는 다른 많은 방법과는 관련이 없습니다. 그러나 사람들이 보는 것과 비 Java 개발자가 Java에 대해 생각할 때 기억하는 것입니다.


9

자바는이 때문에 느리다의 명성이 있었다 천천히. Java의 첫 번째 버전은 Just In Time 컴파일이 없거나 좋지 않았습니다. 이것은 바이트 코드 임에도 불구하고 코드가 해석되고 있었기 때문에 (두 정수를 추가하는 것과 같은) 가장 간단한 연산이라도 기계는 모든 종류의 비교와 포인터 역 참조 및 함수 호출을 수행해야했습니다. JIT 컴파일러는 계속 개선되었습니다. 이제 C ++ 코드를 부주의하게 작성하고 Java 코드를 부주의하게 작성하는 경우 JIT 컴파일러가 불필요한 포인터 역 참조가 있고 나를 위해 처리한다는 사실을 알고 있기 때문에 Java가 때때로 C ++ 보다 성능이 뛰어 납니다.

JIT 컴파일의 차이가 얼마나 큰지 보려면 Computer Languages ​​Benchmark Game 에서 해석 된 벤치 마크와 해석되지 않은 벤치 마크를 확인하십시오 . (Pidigits는 외부 라이브러리를 사용하여 모든 계산을 수행하므로 벤치 마크가 변경되지 않고 다른 라이브러리는 6-16 배의 속도 향상을 보여줍니다!)

이것이 주된 이유입니다. 문제를 해결하지 못한 여러 가지 다른 적은 이유가 있습니다. 원래 Java 시작 시간이 느 렸습니다 (현재는 수정되었습니다). Java의 웹 앱은 다운로드하는 데 시간이 오래 걸립니다 (현재 광대역에 액세스 할 수 있고 영화와 같은 많은 것들이 예상되는 경우). UI Swing은 성능을 염두에두고 작성되지 않았으며 아직 작성되지 않았으므로 C ++과 같은 기능보다 훨씬 덜 까다 롭습니다.


6

Java는 하루 만에 느려졌습니다. 몇 세대의 성능 향상 으로 인해 훨씬 ​​빨라졌습니다 . 마지막으로 들었습니다. 일반적으로 C # 속도의 10 % 이내이며 때로는 더 빠르며 때로는 느립니다.

Java 애플릿 시작은 전체 JVM을 시작해야하기 때문에 여전히 느리며, 모든 JVM을로드해야합니다. 다른 컴퓨터를 부팅하는 것과 같습니다. JVM이 시작되면 상당히 빠르지 만 시작은 일반적으로 사람들이 기억하는 것입니다.

또한 Java의 생존 가능성을 절대 믿지 않는 사람최소한 몇 명 있습니다.


1
불행히도 JVM 시작은 CLR 시작보다 훨씬 느립니다. 이것은 썬이 Java 7을 출시 할 때 최악의 방법으로 발을 끌었 기 때문입니다. 따라서 우리는 4 년 된 Java 6 에 대한 증분 패치를 고수했습니다 .
BobMcGee

3
와우, Java 6은 4 살입니까? 그렇습니다 (베타를 계산하면). 여전히 새로운 느낌이 들었습니다. 직장에서 1.4 사용을 중단했습니다.
Kaleb Brasee

Java 1.4는 사용할 수 있지만 1.5와 1.6은 많은 성능 향상과 구문 설탕을 추가했기 때문에 짜증납니다. 그 이후로 경계 검사 및 System.arraycopy 최적화가 도입되었습니다. 동기화가 많이 개선되었습니다. 1.4가 진정으로 느리다고 말하는 것이 공정하다고 생각합니다.
BobMcGee

LOL, 알고 있습니다. 수동으로 반복하거나 일반 목록 대신 배열을 사용해야 할 때마다 랩톱을 반으로 나누고 싶습니다 ... IBM은 실제로 몇 년 동안 WAS 6.1에서 Java 5를 사용할 수 있었지만 ve는 WAS 6.0을 고수했습니다. (저는 Java 5/6을 사용하고 있지만 실제로는 이전 서버 버전으로 제한되어 있습니다. 1.4에서 최신 버전으로 두 자리 수 퍼센트의 성능 향상이 있습니다. 많은 것들을 위해, 그리고 나는 그들을 고대하고 있습니다.
Kaleb Brasee

6

스테파노 :

나는 처음부터 Java를 사용해 왔기 때문에 내 관점에서 응답 속도가 느린 GUI 프론트 엔드 (AWT 및 스윙)와 애플릿에서 느린 시작이라는 명성이 생겼습니다. VM.

Java는 VM 영역에서 많은 연구를 규정하고 추진했으며 가비지 수집 (실제로 많은 것을 조정할 수 있지만 기본값 만 사용되는 시스템을 보았습니다) 및 핫스팟을 포함하여 상당히 개선되었습니다 최적화 (처음에는 서버 쪽에서 더 효율적일 수 있음).

백엔드 및 계산 수준의 Java는 그렇게 느리지 않습니다. 콜트 는 가장 좋은 예 중 하나입니다.

안정적인 최신 콜트 릴리스는 JDK ibm-1.4.1, RedHat 9.0, 2x IntelXeon@2.8 GHz에서 1.9 Gflop / s 장벽을 뛰어 넘습니다.

실시간 Java 또는 Javolution 과 같은 속도를 향상시키는 특수 메커니즘 뿐만 아니라 gcj와 같은 Ahead-Of-Time 컴파일과 같이 주류 Java 외부에서 고려해야 할 사항이 많이 있습니다 . 또한 Java 바이트 코드를 직접 실행할 수있는 IC가 있습니다 (예 : 현재 iPhone 및 iPod ARM Jazelle 에있는 것과 같은) .

저는 일반적으로 오늘날의 정치적 결정 (iPhone / iPod에서 Java 지원이없는 것과 같은)과 Java에 대한 언어 결정 (많은 사람들이 너무 장황하다고 생각하기 때문에)이라고 생각합니다.

그러나 요즘 Java VM에는 다른 언어가 많이 있습니다 (예 : Python, Ruby, JavaScript, Groovy, Scala 등).

개인적으로 저는 가장 작은 도구 (예 : JavaCard)에서 가장 큰 서버에 이르기까지 모든 작업을 수행 할 수있는 뛰어난 툴링 및 라이브러리 가용성을 갖춘 유연하고 안정적인 플랫폼으로 계속 즐기고 있습니다.


자, 또 다른 나쁜 평판은 GUI 툴킷에서 나왔습니다. 물론 현대 JVM이 기본 위젯을 사용하기 때문에 OS 라이브러리에 연결되어 있다고 가정합니까? 또는 AWT / Swing을 사용하여 호스트 플랫폼과 동일한 모양과 느낌을 제공합니까?
Stefano Borini

Stefano : Swing은 실제로 위젯의 비 네이티브 범용 렌더링이라는 아이디어를 기반으로하므로 가정이 잘못되었습니다. 실제로는 스윙 컴포넌트가 기본 컴포넌트의 모양을 에뮬레이트 할 수있게하는 "플러그 가능 룩앤필"메커니즘입니다. 그런 것을 찾고 있다면 SWT ( eclipse.org/swt ) 를 확인 하고 네이티브 OS에 연결하고 JNI (병목 현상이라고 함)를 사용하여 네이티브 위젯을 사용할 수 있습니다.
Dieter

요즘 Java2D (Swing에 사용)는 매우 빠르며 기본 위젯 (SWT)을 사용하면 성능 이점이 없습니다. 적어도 6 개월 전에 Swing 또는 SWT를 배울 지 결정할 때 읽은 내용입니다.
Luigi Plinge

4

반죽은 다른 많은 도구보다 반죽을 굴릴 때 속도가 훨씬 느립니다. 해머를 "느리게"만들거나 설계된 작업에 덜 유용하지는 않습니다.

일반적인 프로그래밍 언어 인 Java는 다양한 프로그래밍 작업을 위해 많은 (많은 것은 아니지만) 수준에 있습니다. Java가 "금속에 더 가까운"언어보다 덜 복잡한 언어에서는 수작업으로 코딩 된 솔루션보다 성능이 우수하지 않은 구체적인 테스트가 있습니다.

그러나 "실제 응용 프로그램"과 관련하여 Java는 종종 올바른 도구입니다. 이제는 개발자가 ANY 도구를 사용하여 성능이 느린 솔루션을 만드는 것을 막을 수는 없습니다. 도구의 오용은 잘 알려진 문제입니다 (PHP와 VB의 평판을보십시오). 그러나 Java의 (주로) 깨끗한 디자인과 구문은 오용을 줄이기 위해 많은 역할을합니다.


3

Java는 고급 언어이며, 오늘날 평판이 다른 다른 고급 언어와 동등한 성능을 유지하는 것이 명성입니다.

  1. 이 갖는 동적 바인딩을 의미한다. 비가 상 메소드가 함수 호출로 컴파일되는 C ++과 비교할 때 세계 최고의 Java 컴파일러조차 비효율적 인 코드를 생성해야합니다. 그러나 더 깨끗하고 높은 수준의 의미도 있습니다.

  2. 나는 세부 사항을 기억하지 못하지만 Java 초기에 Java 객체 당 뮤텍스가 있다고 들었고 각 방법으로 획득하고 릴리스했습니다. 불행히도 객체 당 뮤텍스만이 경쟁이나 교착 상태 또는 동시 프로그램에서 발생할 수있는 나쁜 것들로부터 당신을 보호하지는 않지만 동시성에 더 잘 적응하는 경향이 있습니다. 그 부분은 사실이라면 조금 순진하지만 좋은 의도에서 나왔습니다. 이 측면에 대해 더 많이 알고 있다면 세부 사항을 자유롭게 작성하십시오.

  3. Java가 고급 언어 인 또 다른 방법은 Garbage-Collection을 사용하는 것 입니다. 가비지 컬렉션보다 느려질 수 있습니다 mallocfree그와 모든 그들이 필요로하는 메모리와 작업을 한 번에 할당 프로그램. 문제는 가비지 콜렉션이없는 언어에서 프로그래머 가 한 번에 필요한 모든 메모리를 할당하고 임의의 최대 크기 상수가 오버플로 된 경우 실패하는 프로그램 작성하는 경향이 있다는 것입니다. 따라서 비교는 사과와 오렌지입니다. 프로그래머가 GC 이외의 언어로 체인 구조를 동적으로 할당하여 프로그램을 작성하고 디버그하려고 할 때 때때로 프로그램이 GC 언어보다 빠르지 않다는 것을 알게됩니다.malloc 하고free무료가 아닙니다! 또한 오버 헤드가 있습니다. 또한, 누가 어떤 기능을 해제 할 것인지를 지정하기 위해 GC가 필요하지 않으며, 누가 어떤 기능을 해제 할 것인지를 지정해야하는 경우가 있습니다. GC 언어에서는 복사가 필요하지 않았지만 마지막으로 사용할 것입니다.


1. HotSpot에는 해당되지 않을 수 있습니다. 2. 메소드를 동기화 된 것으로 표시 한 경우에만.
Winston Ewert

1
1. 컴파일러는 코드를 최적화하지 않지만 JVM은 일반적으로 하나 또는 두 개의 가상 메소드 만 동적으로 판별 할 수있을 정도로 똑똑하며 정적 또는 인라인으로 호출 할 수 있습니다. C ++이 가상 메소드를 인라인 할 수 없다고 확신합니다. 2. 모든 Java 오브젝트에는 잠금이 있습니다. 각 객체에 약간의 오버 헤드 (약 1 바이트)가 있지만 사용하지 않으면 거의 영향을 미치지 않습니다. 3. Java에서는 필요한 모든 객체를 한 번에 할당 할 수 있습니다. 이것은 하루 종일 GC가 아닌 응용 프로그램을 제공 할 수 있습니다. ;) Java의 GC는 암시 적으로 멀티 스레드이며 C ++의 특수 라이브러리가 필요합니다.
피터로 레이

C ++은 가상 호출을 인라인 할 수 있지만 Java는 더 많은 경우에이를 수행 할 수 있으며 메가 모픽 호출 사이트를 최적화 할 때 더욱 강력합니다.
Piotr Kołaczkowski

2

90 년대 중반 자바가 주류에 부딪쳤을 때 C ++은 지배적 인 언어였으며 웹은 여전히 ​​새롭습니다. 또한 JVM과 GC는 주류 개발에서 비교적 새로운 개념이었습니다. 초기 JVM은 느려졌으며 (베어 메탈에서 실행되는 C ++과 비교할 때) 가비지 콜렉션 일시 정지가 길어 Java가 느리다는 평판을 얻었습니다.


이것은 GC의 기술로 인한 것입니까? GC 단계에서보다 효율적으로 사용할 수있는 몇 가지 전략 (예 : 개체의 세대 계층)이 있다는 것을 알고 있습니다. 당시 전략은 무엇입니까?
Stefano Borini

1
IANA JVM 전문가이지만 GC에 사용되는 단일 스레드 마크 / 스윕 알고리즘이 있었기 때문에 GC를 수행하는 동안 전체 JVM을 일시 중지해야한다고 생각합니다. 요즘에는 동시 마크 / 스윕이 있으며 JVM에는 다른 많은 성능 향상 기능도 있습니다.
Ken Liu

2
최신 GC 알고리즘은 훌륭하지만 가장 큰 개선은 JIT라고 생각합니다.
Pascal Thivent

1

많은 Java 데스크탑 앱 (이번 : Eclipse와 같은 것)은 메모리 소비가 높고 클래스 로더가 많은 IO를 수행 할 수 있기 때문에 GUI 응답 성이 좋지 않습니다. 그것은 개선되고 있지만 몇 년 전에 악화되었습니다.

많은 (대부분의) 사람들은 일반화를 좋아하기 때문에 "자바는 느립니다"라고 말합니다. 왜냐하면 그들은 상호 작용할 때 앱이 느리다는 것을 인식하기 때문입니다.


높은 메모리 소비가 도구 또는 Java 라이브러리에서 발생한다고 생각하십니까?
Stefano Borini

Eclipse의 경우-Eclipse 인프라 자체에서. 과거의 "무거운"GUI (JBuilder를 기억하는대로)와 동일합니다. 정적 형식의 언어로 플러그인 아키텍처 (예 : Eclipse)를 사용하려면 많은 상용구 객체가 필요하기 때문에 느낌이 듭니다. Emacs는 플러그인도 가지고 있으며 일반적인 코딩을 할 때 메모리 소비는 Eclipse보다 10-20 배 적습니다. Emacs Lisp 코드는 바이트 코드로 컴파일되어 emacs 인스턴스에로드 된 다음 Java 클래스 로더와 유사하게 실행됩니다. Java에는 플러그 인을 허용하기 위해 인스턴스화 된 수많은 중간 객체가 있다고 생각합니다.
Wojciech Kaczmarek

1

Java 애플리케이션의 주요 문제점 은 주식 런타임 라이브러리의 크기가 크기 때문에 크기 가 크다는 것입니다 . 거대한 프로그램은 메모리를 많이 채우고 스왑하는 경향이 있으므로 느려집니다.

Sun JVM이 큰 이유는 많은 것들을 추적하여 작동하는 매우 우수한 바이트 코드 인터프리터를 가지고 있기 때문입니다. 그것은 많은 데이터, 즉 메모리를 의미합니다.

jamvm 가상 머신은 합리적으로 빠른 인터프리터 (기본 코드 없음)이며 매우 작습니다. 심지어 빨리 시작합니다.


1

Pascal이 말했듯이 Java는 다른 고급 언어와 동등합니다. 그러나 Windows 98 에서 원래 JVM으로 작업 한 사람으로서 Java 가상 머신이 제공하는 추상화 수준은 고통 스러울 것입니다.

기본적으로 그것은 오늘날 JVM에서 당연한 것으로 거의 또는 전혀 최적화되지 않은 소프트웨어 에뮬레이션이었습니다.


0

사람들은 일반적으로 "통역"라인을 트로트합니다. 옛날 옛적에 그렇기 때문에 Java를 '너무 느리게'덤프하고 새로운 버전을 테스트하기 위해 다시는 돌아 오지 않은 사람들이 나쁜 언론을 나눠주기 때문입니다.

또는 아마도 "사람은 바보"일 것입니다.


0

언젠가는 너무 가까운 미래에 JIT 컴파일 언어가 JIT 컴파일러가 런타임을 많이 사용할 수 있기 때문에 모든 측면에서 컴파일 언어보다 성능이 뛰어납니다 (시작 시간 / 메모리 소비가 아닐 수 있음) 동작 및 실행중인 플랫폼


6
난 당신이 무슨 생각 을 의미 하는 JIT 컴파일 (안 해석) 코드가 AOT 코드를 이길 것입니다 말할 수 있습니다. 컴파일 된 코드를 실행하는 것보다 항상 해석이 느립니다. 이것이 JIT 컴파일러가 사용되는 이유입니다. 캐치 : JIT 컴파일러가 더 빨리 컴파일해야하고 런타임 정보를 사용하여 최적화를 암시 할 수 있다는 점을 제외하면 출력 측면에서 사전 컴파일러와 JIT 컴파일러간에 차이가 거의 없습니다. 플랫폼 별 최적화 기능을 갖춘 플랫폼 별 AoT 컴파일러는 최적화에 소요되는 시간에 제한이 없기 때문에 거의 항상 JIT를 능가합니다.
BobMcGee

답을 주셔서 감사합니다. JIT 컴파일러가 처리해야 할 시간을 생각하지 마십시오.
helpermethod

핫스팟 적응 최적화와 같은 것입니까?
스테파노 보리 니

2
@BobMcGee : 매우 그렇습니다. C ++ 프로그램은 모든 작업에 대한 프로파일 피드백으로 느리게 실행되도록 빌드 할 수 있습니다. 그런 다음 컴파일러는 30 분의 CPU 시간과 2GB의 RAM을 사용하여 매우 빠른 버전을 자유롭게 재구성 할 수 있습니다. 이렇게 한 JIT는 사용자를 떠날 것입니다.
Zan Lynx

1
JIT 컴파일 시간은 서버와 같이 오래 실행되는 앱에서는 무시할 수 있습니다. PGO가있는 AOT는 2 가지 이상의 이유로 JIT에 비해 더 제한적입니다. 첫째, 대부분의 성능 차이는 경량 최적화로 달성됩니다. gcc -O2와 gcc -O3를 비교하십시오. 대부분의 경우 차이없으며 때로는 -O3이 약간 나아질 수 있으며 때로는 약간 나빠질 수는 있지만 이보다 2 배 이상 큰 차이는 없었습니다. 둘째, PGO와 함께 AOT를 사용하면 프로필이 사용 사이트에 어떤 것인지 추측 할 수 있습니다. 잘못 생각하면 JIT보다 훨씬 뒤쳐져 있습니다. 실제 프로파일은 구성에 따라 크게 달라질 수 있습니다.
Piotr Kołaczkowski
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.