programing

자바가 정말 느려요?

javaba 2022. 7. 17. 11:43
반응형

자바가 정말 느려요?

자바는 느리기로 어느 정도 정평이 나 있다.

  • 자바가 정말 느려요?
  • 그렇다면 왜?병목현상은 어디에 있습니까?비효율적인 JVM 때문인가요? 가비지 컬렉션 때문인가요?JNI로 감싸진 C 코드 대신 순수 바이트 코드 라이브러리?많은 다른 언어들이 이러한 기능을 가지고 있지만, 느리다는 평판은 없습니다.

현대 자바는 여전히 메모리 호그이지만 가장 빠른 언어 중 하나입니다.Java는 VM을 시작하는 데 오랜 시간이 걸리기 때문에 속도가 느리다는 평판을 받았습니다.

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

이제 "느린" Java 애플리케이션에 대한 변명은 없습니다.개발자와 레거시 코드/라이브러리의 책임은 언어보다 훨씬 큽니다.또, 「엔터프라이즈」라고 하는 것은 비난해 주세요.

"Java는 느리다"는 의견을 공평하게 표현하기 위해 다음과 같이 여전히 느리다(2013년 업데이트).

  • 라이브러리는 퍼포먼스가 아닌 정확성과 가독성을 목적으로 작성되는 경우가 많습니다.이것이 자바가 특히 서버측에서 여전히 나쁜 평판을 받고 있는 주된 이유라고 생각합니다.이로 인해 String 문제가 기하급수적으로 악화됩니다.단순한 실수가 몇 가지 있습니다.원본 대신 오브젝트가 사용되는 경우가 많아 퍼포먼스가 저하되고 메모리 사용량이 증가합니다.많은 Java 라이브러리(표준 라이브러리 포함)는 가변형 또는 단순한 형식(char[] 또는 StringBuffer)을 재사용하지 않고 String을 자주 만듭니다.이것은 느리고 나중에 수집하기 위해 엄청난 양의 쓰레기를 만든다.이를 해결하기 위해 개발자들은 원시 컬렉션, 특히 가능하면 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에서 부분적으로 기인합니다.이를 능가하는 C를 코드화할 수 있지만(커스텀 메모리 관리를 롤하고 효율적으로 malloc을 실행함으로써), 쉽지 않다.

  • 메서드 콜은 기본적으로 무료이며 경우에 따라서는 큰 메서드코드보다 빠릅니다.HotSpot 컴파일러는 실행 정보를 사용하여 메서드 호출을 최적화하고 매우 효율적인 인라인 기능을 제공합니다.추가 실행 정보를 사용하면 사전 컴파일러 및 수동 인라인 처리보다 성능이 뛰어난 경우도 있습니다.C/C++와 비교하여 컴파일러가 인라인하지 않을 경우 메서드 호출에 약간의 성능 불이익이 발생합니다.

  • 동기화와 멀티스레딩은 쉽고 효율적입니다.자바는 처음부터 스레드 인식으로 설계되어 있습니다.최신 컴퓨터는 보통 여러 개의 코어를 갖추고 있으며, 스레드가 언어에 내장되어 있기 때문에 매우 쉽게 이용할 수 있습니다.기본적으로 표준 싱글 스레드 C 코드와 비교하여 100~300%의 속도 향상을 실현합니다.네, C 스레드와 라이브러리는 주의 깊게 작성하면 이 문제를 극복할 수 있지만 프로그래머에게는 많은 추가 작업이 필요합니다.

  • 문자열에는 길이가 포함됩니다.일부 작업은 더 빠릅니다.이것은 늘 구분 문자열(C에서 공통)을 사용하는 것보다 우선합니다.Java 7에서 Oracle은 String.subString() 최적화를 삭제했습니다.이는 사람들이 String을 잘못 사용하여 메모리 누수가 발생했기 때문입니다.

  • 어레이 복사는 고도로 최적화되어 있습니다.최신 버전에서는 Java가 시스템용으로 수동 조정된 어셈블러를 사용합니다.어레이 카피그 결과, 어레이 카피/메모 카피 부하가 높은 조작에서는, C 의 코드에 상당하는 마진수를 웃도는 것을 볼 수 있었습니다.

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

"자바는 느리다"는 평판에 기여한 몇 가지 다른 역사적 사실들이 있다.

  • JIT 컴파일(Java 1.2/1.3) 이전에는 언어가 해석되었을 뿐 컴파일되지 않았기 때문에 매우 느렸습니다.
  • JIT 컴파일이 효율화하는 데 시간이 걸렸다(버전별로 대폭 개선)
  • 클래스 로딩은 몇 년 동안 훨씬 더 효율적이 되었습니다.이전에는 기동시에 매우 비효율적이고 느렸습니다.
  • Swing 및 UI 코드는 네이티브 그래픽 하드웨어를 잘 사용하지 않았습니다.
  • 스윙은 정말 끔찍해요.왜 자바가 데스크톱 PC에 전혀 적응하지 못했는지 나는 AWT와 Swing을 탓한다.
  • 라이브러리 클래스에서 동기화를 많이 사용하므로 동기화되지 않은 버전을 사용할 수 있습니다.
  • 네트워크를 통해 전체 JAR을 전송하고 VM을 로드하여 부팅하기 때문에 애플릿을 로드하는 데 시간이 오래 걸립니다.
  • 성능 저하가 큰 동기(각 Java 버전에 최적화되어 있음)를 수반하는 데 사용됩니다.하지만 반성은 여전히 비용이 많이 든다.

처음에 Java는 특별히 빠르지는 않았지만 지나치게 느리지도 않습니다.요즘 자바는 매우 빠르다.지금까지 이야기한 사람들로부터 자바가 느리다는 느낌은 다음 두 가지에서 비롯된다.

  1. VM 시작 시간이 느리다.초기 Java 구현은 네이티브 애플리케이션에 비해 필요한 라이브러리와 애플리케이션을 시작하고 로드하는 데 오랜 시간이 걸렸습니다.

  2. UI가 느리다.얼리 스윙은 느렸다.대부분의 Windows 사용자가 기본 Metal L&F가 못생겼다고 생각하는 것도 도움이 되지 않을 것입니다.

위의 점들을 고려할 때, 사람들이 '자바는 느리다'는 인상을 받는 것은 놀랄 일이 아니다.

네이티브 어플리케이션 또는 Visual Basic 어플리케이션 개발에 익숙한 사용자나 개발자에게 이 두 가지 포인트는 어플리케이션에서 가장 눈에 띄는 것으로, 어플리케이션에 대한 첫인상이 됩니다(1.만 해당).

코드 실행과 시작 시간이 전혀 연결되어 있지 않은 경우에도 응용 프로그램의 시작 시간이 즉시 시작되는 이전 Visual Basic 응용 프로그램과 비교하여 "매우 빠르게 코드가 실행됨"을 사용자에게 납득시킬 수 없습니다.

첫인상을 망치는 것은 루머와 신화를 시작하는 좋은 방법이다.그리고 소문과 신화는 없애기 어렵다.

한마디로 Java는 느리지 않다."자바는 느리다"는 사람들의 생각은 10여 년 전 자바에 대한 첫인상을 바탕으로 한다.

자바가 느리지 않다는 댓글로 가득 찬 페이지를 읽은 후, 저는 다른 의견으로 대답하면 됩니다.

언어의 느림은 '빠른'에 대한 당신의 기대치에 크게 좌우된다.C#이 빠르다고 생각하면 Java도 빠르네요.문제 도메인이 데이터베이스 또는 반실시간 처리와 관련된 경우 Java도 충분히 빠릅니다.하드웨어를 추가하여 애플리케이션을 확장할 수 있다면 Java가 빠를 수 있습니다.5~10의 지속적인 속도 향상을 고려할 때, Java의 빠른 속도를 고려할 필요가 있습니다.

대규모 데이터 세트에 대해 수치 계산을 수행하거나 CPU 리소스가 제한된 실행 환경에 바인딩된 경우 5~10 범위의 지속적인 속도 향상이 발생합니다.0.5의 속도라도 계산 완료 시간이 500시간 단축될 수 있습니다.이러한 경우 Java는 최종 성능을 얻을 수 없으며 Java는 느리다고 생각할 수 있습니다.

당신은 두 가지 질문을 하고 있는 것 같습니다.

  1. Java는 정말 느리고, 느리다면 그 이유는 무엇입니까?
  2. 왜 Java는 많은 대안보다 빠르지만 느리다고 인식될까요?

그 중 첫 번째는 어느 정도 "줄은 얼마나 긴가"라는 질문입니다.'느리다'는 당신의 정의로 귀결됩니다.순수 인터프리터에 비해 자바는 매우 빠릅니다.(통상은) 어떤 종류의 바이트 코드로 컴파일된 다음 기계 코드로 동적으로 컴파일되는 다른 언어(C# 등)와 비교합니다.NET) Java는 대략 동등합니다.보통 순수한 기계 코드로 컴파일되어 최적화 기능(예를 들어 C, C++, Fortran, Ada)을 향상시키는 것만으로 작업하는 (대부분의) 사람들과 비교하면 Java는 몇 가지 점에서 꽤 잘 수행되지만 전체적으로 적어도 다소 느린 경향이 있습니다.

이 대부분은 주로 구현과 관련되어 있습니다.기본적으로 사용자가 다이내믹/J에서 대기하고 있다는 사실로 귀결됩니다.IT 컴파일러가 실행되기 때문에 처음부터 오랜 시간 동안 실행할 수 있는 프로그램이 없는 한 컴파일러가 어려운 최적화에 많은 시간을 할애하는 것은 정당화하기 어렵습니다.따라서 대부분의 Java(및 C# 등) 컴파일러는 매우 어려운 최적화에 많은 노력을 기울이지 않습니다.대부분의 경우 최적화가 수행되는 것보다 적용되는 위치가 중요합니다.대부분의 최적화 문제는 NP가 완료되어 있기 때문에 공격받는 문제의 크기에 따라 시간이 빠르게 증가합니다.시간을 합리적으로 유지하는 한 가지 방법은 최적화를 한 번에 하나의 기능에만 적용하는 것입니다.개발자가 컴파일러를 기다리는 경우, 훨씬 더 오랜 시간을 들여 훨씬 더 큰 프로그램 청크에 동일한 최적화를 적용할 수 있습니다.마찬가지로 일부 최적화의 코드는 상당히 복잡합니다(따라서 매우 클 수 있습니다).또, 유저는 코드가 로드되는 동안 대기하고 있기 때문에(또한 JVM의 기동 시간이 전체 시간에서 중요한 요소가 되는 경우가 많다), 실장에서는, 한 장소에서 절약된 시간과 다른 장소에서 손실된 시간의 밸런스를 잡을 필요가 있습니다.게다가, 코드의 메리트가 적은 것을 고려하면, 통상, JVM의 사이즈를 작게 유지하는 것이 보다 유리합니다.

두 번째 문제는 Java에서는 어느 정도 "모든 것에 맞는" 종류의 솔루션을 자주 사용할 수 있다는 것입니다.예를 들어, 많은 자바 개발자들에게 Swing은 본질적으로 유일한 윈도우 라이브러리이다.C++와 같은 제품에는 말 그대로 수십 개의 윈도우 라이브러리, 애플리케이션 프레임워크 등이 있으며, 각 라이브러리에는 사용 편의성 대 빠른 실행, 일관된 모양과 느낌 대 네이티브 모양과 느낌 등의 타협점이 있습니다.유일한 진짜 걸림돌은 일부(예: Qt)는 상당히 비쌀 수 있다는 것입니다(적어도 상업적 용도로는).

셋째, C++로 작성된 많은 코드(그리고 더 많은 코드)는 단순히 더 오래되고 더 성숙합니다.그 대부분은 수십 년 전에 작성된 루틴의 핵심을 포함하고 있습니다.그때 코드 최적화는 정상적이고 예상되는 동작이었습니다.이는 종종 더 작고 빠른 코드에 실질적인 이점이 있습니다.C++(또는 C)는 코드가 작고 빠르다는 것은 인정받지만, 실제로는 개발자의 산물과 코드 작성 시간의 제약에 더 가깝습니다.어느 정도 자기충족적 예언으로 이어집니다.속도에 신경을 쓸 때 사람들은 종종 C++를 선택합니다. 왜냐하면 C++는 평판이 좋기 때문입니다.그들은 최적화에 더 많은 시간과 노력을 들였고, 새로운 세대의 빠른 C++ 코드가 작성되었습니다.

요약하자면, Java의 일반적인 구현은 기껏해야 최대 최적화에 문제가 있습니다.게다가 Java가 보이는 곳에서는 윈도우 툴킷이나 JVM의 기동시간 등이 언어 자체의 실행속도보다 큰 역할을 하는 경우가 많습니다.많은 경우 C와 C++는 단순히 최적화를 위해 노력함으로써 얻을 수 있는 진정한 성과에 대해서도 인정받고 있습니다.

두 번째 질문입니다만, 업무상 인간성의 문제라고 생각합니다.몇몇 광신도들은 자바의 속도가 눈부시게 빠르다고 다소 과장된 주장을 한다.누군가가 그것을 시험해 보고, 사소한 프로그램도 시작하는 데 몇 초가 걸리고, 실행이 되면 느리고 서툴러진다는 것을 알게 된다.JVM의 기동 시간이 대부분이라는 것을 알기 위해 분석하려고 애쓰는 사람은 거의 없을 것입니다.처음 테스트했을 때는 아직 코드가 컴파일되지 않았습니다.코드의 일부는 해석되고 일부는 컴파일되어 대기하고 있습니다.게다가, 충분히 빨리 실행해도, 대부분의 유저에게는 외관이나 느낌이 이질적이고 서투르게 느껴지기 때문에, 객관적인 측정에서는 응답 시간이 빠르다고 해도, 여전히 서투르게 느껴집니다.

이것들을 합치면, 꽤 간단하고 자연스러운 반응을 얻을 수 있다.자바는 느리고 못생기고 서투르다.그것이 정말 빠르다는 과대 광고를 보면, "약간 더 정확하고, 대부분 특정한 상황에서"가 아니라, 지나치게 반응하고 끔찍하게 느리다고 결론짓는 경향이 있다.이것은 일반적으로 언어로 처음 몇 개의 프로그램을 작성하는 개발자에게 최악의 상황입니다.대부분의 언어에서 "hello world" 프로그램은 즉시 실행되지만 Java에서는 JVM이 시작될 때 쉽게 일시 중지됩니다.꽉 막힌 루프에서 훨씬 더 느리게 실행되는 순수한 인터프리터라도 이와 같은 코드에서는 단순히 로드되어 조금 더 빨리 실행되기 때문에 여전히 더 빨리 나타날 수 있습니다.

Java 초기(1990년대 중후반)의 오래된 정보입니다.Java의 모든 주요 버전은 이전 버전에 비해 상당한 속도 향상을 도입했습니다.Oracle이 JRockit과 Sun의 JVM for Java 7을 합병함에 따라 이 추세는 계속될 것으로 보인다.

다른 많은 인기 있는 현대 언어(Python, Ruby, PHP)와 비교했을 때, 사실 Java는 대부분의 사용에서 훨씬 더 빠릅니다.C 또는 C++와 완전히 일치하지 않지만 많은 작업에서 충분히 가깝습니다.진정한 퍼포먼스의 우려는 최종적으로 어느 정도의 메모리를 사용하는가 하는 것입니다.

기동 시간이 길어지는 주범은 동적 링크다.Java 응용 프로그램은 컴파일된 클래스로 구성됩니다.각 클래스는 다른 클래스(인수 유형, 메서드 호출 등)를 이름으로 참조합니다.JVM은 시작 시 이러한 이름을 검사하고 일치시켜야 합니다.항상 필요한 부분만 수행하면서 점진적으로 수행하지만, 여전히 해야 할 일이 있습니다.

C 어플리케이션에서는 이 링크 단계가 컴파일 마지막에 발생합니다.특히 큰 어플리케이션에서는 느리지만 개발자만 볼 수 있습니다.링크하면 OS가 "있는 그대로" RAM에 로드해야 하는 실행 파일이 생성됩니다.

Java에서는 응용 프로그램이 실행될 때마다 링크가 발생합니다.그 때문에, 기동 시간이 길어집니다.

캐싱 기술을 포함한 다양한 최적화가 적용되어 컴퓨터의 속도가 빨라지고(애플리케이션이 「더 커진다」보다 「더 빨라진다」), 최근에는 문제의 중요성이 크게 낮아졌지만, 낡은 편견은 여전합니다.

그 후 퍼포먼스에 대해서는 어레이 액세스(대부분 해시함수 및 기타 암호화 알고리즘)를 사용한 콤팩트한 계산의 벤치마크를 통해 최적화된 C코드가 Java 코드보다 약 3배 빠른 것을 알 수 있습니다.실장된 알고리즘에 따라서는 C코드가 Java 코드보다 30%, C코드가 4배 빠른 경우도 있습니다.프로세서는 64x64->128의 곱셈 연산 코드를 제공하지만 Java는 가장 긴 정수 유형이 64비트이기 때문에 사용할 수 없기 때문에 C 코드가 실제로 큰 정수 산술용 어셈블리일 때 10배 계수를 보았습니다.long이건 엣지 케이스예요실제 상황에서는 I/O 및 메모리 대역폭에 대한 고려 사항으로 인해 C 코드가 Java보다 3배 더 빠르지 않습니다.

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

R, Python, C/C++와 최적화된 멀티스레드 ATLAS 라이브러리를 조합하여 사용합니다.각 언어에서 3000에 3000의 2배의 행렬을 약 4초 만에 곱할 수 있습니다.Java에서 Colt와 Parallel Colt를 사용하면 같은 조작에 185초가 걸립니다!이러한 자바 라이브러리는 본질적으로 평행하지만 놀랍습니다.

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

3GB의 RAM을 탑재한 HP Core 2 Duo 머신입니다.64비트 Ubuntu 10.04(Lucid Lynx)를 사용하고 있습니다.

대부분의 사용자 경험상 Java는 느립니다.애플릿이 뜨기 전에 브라우저 상에서 커피잔이 빙글빙글 돌고 있는 것을 본 적이 있습니다.JVM을 스핀업하고 애플릿 바이너리를 다운로드하는 데 시간이 걸리며, 이는 눈에 띄는 방식으로 사용자 환경에 영향을 미칩니다.

JVM의 느린 스핀업과 애플릿 다운로드 시간이 Java 커피잔과 함께 눈에 띄게 브랜드화 되는 것은 도움이 되지 않기 때문에 사람들은 대기를 Java와 연관짓는다.플래시를 로드하는 데 시간이 오래 걸리는 경우, "로드" 메시지의 브랜딩은 플래시 개발자가 지정하기 때문에 사람들은 플래시 기술 전체를 탓하지 않습니다.

All of this has nothing to do with Java's performance on a server, or in the many other ways that Java gets used outside the browser. But it's what people see, and what non-Java developers remember when they think about Java.

Java has the reputation of being slow because it was slow. The first versions of Java had either no or rather poor Just In Time compilation. This meant that the code, although bytecode, was being interpreted, so even for the simplest operations (like adding two integers) the machine had to do all sorts of compares and pointer dereferences and function calls. The JIT compiler has been ever-improving; now it's at the point where if I write C++ code carelessly and Java code carelessly, Java will sometimes outperform C++ because the JIT compiler realizes that I've got some unnecessary pointer dereferencing and will take care of it for me.

If you want to see just how big a difference JIT compilation makes, check out the interpreted vs. non-interpreted benchmarks at the Computer Languages Benchmark Game. (Pidigits uses an external library to do all the computations, so that benchmark doesn't change; the others show a 6-16x speedup!)

So, that's the main reason. There are a variety of other, lesser reasons that did not help matters: originally, Java startup time was slow (now fixed); web apps in Java take a long time to download (much less true now with widely accessible broadband, and with large things like movies being expected); the UI Swing was not (and still is not) written with performance in mind so it is much less snappy than equivalents in e.g. C++.

Java WAS slow, back in the day. It has become much faster, due to a few generations of performance enhancements. Last I heard, it is usually within 10% of C# speed -- sometimes faster, sometimes slower.

Java applet startup is still slow because you've got to start a whole JVM, which has to load all it's classes. Somewhat like booting another computer. Once the JVM starts it is quite fast, but the startup is usually what people remember.

Also, there are at least a few people that will never believe in the viability of Java.

Stefano:

I have been with Java since the beginning, so from my point of view the fame of being slow was created by non-responsive and slow GUI frontends (AWT, and then Swing) and in Applets probably because of the additional slow startup times of the VM's.

Java has stipulated and promoted a lot of research in the VM area, and there have been quite some improvements, including the garbage collection (you can tune a lot of things actually; however, often I see systems where only defaults are used) and hotspot optimization (which at the beginning and probably still is more efficient on the server side).

Java at the backend and the computational level is not that slow. Colt is one of the best examples:

The latest stable Colt release breaks the 1.9 Gflop/s barrier on JDK ibm-1.4.1, RedHat 9.0, 2x IntelXeon@2.8 GHz.

There are many things outside mainstream Java that should be considered, like Realtime Java or special mechanisms to enhance the speed like Javolution, as well as Ahead-Of-Time compilation (like gcj). Also, there are IC's that can execute Java Bytecode directly, like for example the one that is in the current iPhones and iPods ARM Jazelle.

I think that generally today it's a political decision (like no Java support on the iPhone/iPod), and a decision against Java as a language (because many think it is too verbose).

However, there are many other languages for the Java VM nowadays (e.g. Python, Ruby, JavaScript, Groovy, Scala etc.) which may be an alternative.

Personally I continue to enjoy it as a flexible and reliable platform, with excellent tooling and library availability, that allows one to work with everything from the smallest device (e.g. JavaCard) to the largest servers.

A hammer is much slower at rolling out dough than many other tools. Doesn't make the hammer "slower", nor less useful for the tasks that it is designed to do.

As a general programming language, Java is on par with many (if not most) for a wide array of programming tasks. There are specific, trivial tests for which Java will not outperform hand-coded solutions in less sophisticated languages, ones that are "closer to the metal".

But when it comes to "real world applications", Java often is the Right Tool. Now, that said, nothing will stop developers from making a slow-performing solution using ANY tool. Misuse of tool is a well known problem (just look at PHP's and VB's reputations). However, Java's (mostly) clean design and syntax does do a lot to reduce misuse.

Java is a high-level language and its reputation nowadays is to have performance on par with other, comparable high-level languages.

  1. It has dynamic binding semantics. Compared to C++ where non-virtual methods are compiled as function calls, even the best Java compiler in the world has to produce code that is less efficient. But it's also a cleaner, more high-level semantic.

  2. I do not remember the details, but I heard in the early days of Java that there was a mutex per Java object, to be acquired and released by each method. That tends to make it better adapted to concurrency, although unfortunately just a mutex per object will not protect you from races or deadlocks or any of the bad things that can happen in concurrent programs. That part, if true, is a little naive, but it came from good intentions. Feel free to fill me in on the details if you know more about this aspect.

  3. Another way in which Java is a high-level language is by having Garbage-Collection. Garbage-Collection may be slower than malloc and free for programs that allocate at once all the memory they need and work with that. The problem is, in languages that do not have Garbage-Collection, programmers tend to write only programs that allocate all the memory they need at once and fail if it turns out some arbitrary maximum size constant has been overflown. So the comparison is apples to oranges. When programmers make the effort to write and debug programs with dynamic allocation of chained structures in non-GC languages, they sometimes find that their programs are no longer faster than in a GC language, because malloc and free are not free! They have overhead too... Plus, not having a GC forces to specify who frees what, and having to specify who frees what in turn sometime forces you to make copies — when several functions are going to need the data and it's not clear which will be using it last — whereas copying wouldn't have been necessary in a GC language.

In the mid-nineties when Java hit the mainstream, C++ was the dominant language, and the web was still fairly new. Also, JVMs and GC were relatively new concepts in mainstream development. The early JVMs were kind of slow (compared to C++ running on bare metal) and also suffered from sometimes long garbage collection pauses, which led to a reputation of Java being slow.

Many Java desktop apps (these times: things like Eclipse) have bad GUI responsiveness, probably due to the high memory consumption and the fact that classloader can do lots of IO. It's improving but was worse few years ago.

Many (most) people like to do generalizations so they say "Java is slow" because they perceive the apps are slow when they interact with them.

The major problem with java applications is that it is huge due to the large size of the stock runtime library. Huge programs fill a lot in memory and tend to swap, meaning they become slow.

The reason the Sun JVM is large is because it has a very good byte code interpreter which works by keeping track of a lot of things. That means much data, which means memory.

You may want to look at the jamvm virtual machine which is an reasonably fast interpreter (no native code) and very small. It even starts up fast.

As Pascal says, Java is on par with other high-level languages. However, as someone who worked with the original JVMs on Windows 98, at the time the level of abstraction provided by the Java virtual machine was, shall we say, painful.

Basically, it was software emulation with little or no optimization that we take for granted today in the JVM.

People normally trot out the "it's interpreted" line. Because once upon a time, it was, and bad press gets handed down by people who dumped Java as 'too slow' and never returned to test newer versions.

Or perhaps "people are idiots" is a better answer.

I think some day, maybe not in the too-near future, JIT-compiled languages will outperform compiled languages in any aspect (well, maybe not startup time/memory consumption) due to the fact that JIT-compilers can make heavy use of runtime behaviour and the platform they're running on.

ReferenceURL : https://stackoverflow.com/questions/2163411/is-java-really-slow

반응형