Java có thực sự chậm không?


180

Java có một số mức độ danh tiếng là chậm .

  • Java có thực sự chậm không?
  • Nếu đúng thì tại sao? Đâu là (hoặc là) nút cổ chai? Có phải vì JVM không hiệu quả? Thu gom rác thải? Các thư viện mã byte thuần túy thay vì mã C bọc JNI? Nhiều ngôn ngữ khác có các tính năng này, nhưng chúng không có tiếng là chậm.

35
mọi người rất lo lắng ... đừng xem làm thế nào điều này có thể chủ quan, cũng không phải là tranh luận. Tôi tự hỏi nếu một câu hỏi như "tại sao sắp xếp bong bóng chậm" sẽ thu được kết quả tương tự. Tôi đã hỏi một câu hỏi kỹ thuật, và muốn câu trả lời kỹ thuật (mà tôi nhận được), nhưng đóng câu hỏi là chủ quan và lập luận là vô lý.
Stefano Borini

1
Tôi đã đọc hầu hết các bình luận hàng đầu và dường như không có ý kiến ​​nào giải quyết được sự thật rõ ràng rằng các ứng dụng máy tính để bàn dựa trên GUI C # chạy nhanh hơn nhiều so với bất kỳ ứng dụng máy tính dựa trên GUI Java nào, kể cả các ứng dụng hiện đại.
BobTurbo

3
Là một nhà phát triển web phía máy khách đã xử lý các dạng web .net, .net MVC, PHP, Rails, Django và rất nhiều thứ khác ngoài Spring (mà tôi đã nghe là tốt) trong Java, tôi mong đợi hiệu năng / kiến ​​trúc kém từ các đầu cuối được xây dựng bởi các nhóm Java. Tôi nghi ngờ vấn đề thực sự không phải là điểm chuẩn mà là vấn đề đơn giản là có một nhà phát triển Java tầm thường ở ngoài kia. Đó không phải là lỗi của ngôn ngữ. Đó không phải là lỗi của các nhà phát triển Java, những người thực sự trau dồi thủ công của họ và học các ngôn ngữ khác ngoài Java. Tuy nhiên, đó có thể là lỗi của Sun, certs, thập niên 90 và ngành công nghiệp CNTT nói chung.
Erik Reppen

Câu trả lời:


236

Java hiện đại là một trong những ngôn ngữ nhanh nhất, mặc dù nó vẫn là một bộ nhớ. Java tiếng là chậm vì nó được sử dụng để có một thời gian dài cho VM để khởi động.

Nếu bạn vẫn nghĩ Java chậm , hãy xem kết quả trò chơi điểm chuẩn . Mã được tối ưu hóa chặt chẽ được viết bằng ngôn ngữ được biên dịch trước thời hạn (C, Fortran, v.v.) có thể đánh bại nó; tuy nhiên, Java có thể nhanh hơn gấp 10 lần so với PHP, Ruby, Python, v.v. Có những lĩnh vực cụ thể nơi nó có thể đánh bại các ngôn ngữ được biên dịch phổ biến (nếu chúng sử dụng các thư viện chuẩn).

Hiện tại không có lý do gì cho các ứng dụng Java "chậm". Các nhà phát triển và mã / thư viện kế thừa sẽ bị đổ lỗi, nhiều hơn so với ngôn ngữ. Ngoài ra, đổ lỗi cho bất cứ điều gì 'doanh nghiệp.'

Để công bằng cho đám đông "Java chậm", đây là những lĩnh vực vẫn còn chậm (cập nhật năm 2013):

  • Thư viện thường được viết cho "tính chính xác" và dễ đọc, không phải hiệu suất. Theo tôi, đây là lý do chính khiến Java vẫn mang tiếng xấu, đặc biệt là phía máy chủ. Điều này làm cho các vấn đề String trở nên tồi tệ hơn theo cấp số nhân. Một số lỗi đơn giản là phổ biến: các đối tượng thường được sử dụng thay cho nguyên thủy, làm giảm hiệu suất và tăng sử dụng bộ nhớ. Nhiều thư viện Java (bao gồm cả các thư viện tiêu chuẩn) sẽ tạo Chuỗi thường xuyên, thay vì sử dụng lại các định dạng có thể thay đổi hoặc đơn giản hơn (char [] hoặc StringBuffer). Điều này là chậm và tạo ra hàng tấn rác để thu thập sau này. Để khắc phục điều này, tôi đề nghị các nhà phát triển sử dụng các bộ sưu tập nguyên thủy và đặc biệt là các thư viện của Javalestion, nếu có thể.

  • Chuỗi hoạt động hơi chậm. Java sử dụng các đối tượng chuỗi mã hóa UTF-16 bất biến . Điều này có nghĩa là bạn cần nhiều bộ nhớ hơn, truy cập nhiều bộ nhớ hơn và một số thao tác phức tạp hơn so với ASCII (C, C ++). Vào thời điểm đó, đó là quyết định đúng đắn cho tính di động, nhưng nó mang một chi phí hiệu suất nhỏ. UTF-8 có vẻ như là một lựa chọn tốt hơn bây giờ.

  • Truy cập mảng chậm hơn một chút so với C, do kiểm tra giới hạn. Hình phạt trước đây là lớn, nhưng bây giờ là nhỏ (Java 7 tối ưu hóa rất nhiều kiểm tra giới hạn dư thừa).

  • Thiếu truy cập bộ nhớ tùy ý có thể làm cho một số I / O và xử lý mức bit chậm (ví dụ nén / giải nén). Đây là một tính năng an toàn của hầu hết các ngôn ngữ cấp cao hiện nay.

  • Java sử dụng nhiều bộ nhớ hơn C và nếu ứng dụng của bạn bị giới hạn bộ nhớ hoặc băng thông bộ nhớ bị ràng buộc (bộ nhớ đệm, v.v.) thì điều này làm cho nó chậm hơn. Điểm nổi bật là phân bổ / thỏa thuận đang bùng cháy nhanh (tối ưu hóa cao). Đây là một tính năng của hầu hết các ngôn ngữ cấp cao hiện nay và do các đối tượng và việc sử dụng GC thay vì phân bổ bộ nhớ rõ ràng. Cộng với quyết định thư viện xấu.

  • I / O dựa trên luồng chậm do (IMO, lựa chọn kém) để yêu cầu đồng bộ hóa trên mỗi lần truy cập luồng. NIO đã sửa lỗi này, nhưng nó là một nỗi đau để sử dụng. Người ta có thể giải quyết vấn đề này bằng cách đọc / ghi vào một mảng, thay vì một phần tử tại một thời điểm.

  • Java không cung cấp chức năng cấp thấp tương tự như C, vì vậy bạn không thể sử dụng các thủ thuật trình biên dịch nội tuyến bẩn để thực hiện một số thao tác nhanh hơn. Điều này cung cấp tính di động và là một tính năng của hầu hết các ngôn ngữ cấp cao hiện nay.

  • Người ta thường thấy các ứng dụng Java được gắn với các phiên bản JVM rất cũ. Đặc biệt là phía máy chủ. Các JVM cũ này có thể cực kỳ kém hiệu quả, so với các phiên bản mới nhất.

Cuối cùng, Java được thiết kế để cung cấp bảo mật và tính di động với chi phí của một số hiệu năng và đối với một số hoạt động thực sự đòi hỏi khắt khe. Hầu hết danh tiếng của nó cho sự chậm chạp không còn xứng đáng.


Tuy nhiên, có một số nơi Java nhanh hơn hầu hết các ngôn ngữ khác:

  • Phân bổ bộ nhớ và phân bổ lại nhanh và rẻ. Tôi đã thấy các trường hợp trong đó 20% NHANH CHÓNG (hoặc hơn!) Để phân bổ một mảng nhiều kB mới hơn là sử dụng lại một bộ nhớ cache.

  • Tính năng khởi tạo đối tượng và hướng đối tượng được sử dụng rất nhanh (nhanh hơn C ++ trong một số trường hợp), vì chúng được thiết kế ngay từ đầu. Đây là một phần từ GC tốt chứ không phải phân bổ rõ ràng (thân thiện hơn với nhiều phân bổ đối tượng nhỏ). Người ta có thể mã C đánh bại điều này (bằng cách cuộn quản lý bộ nhớ tùy chỉnh và thực hiện malloc hiệu quả), nhưng nó không dễ dàng.

  • Các cuộc gọi phương thức về cơ bản là miễn phí và trong một số trường hợp nhanh hơn mã phương thức lớn. Các HotSpot trình biên dịch sử dụng thông tin thực hiện để tối ưu hóa các cuộc gọi phương pháp và có nội tuyến rất hiệu quả. Bằng cách sử dụng thông tin thực thi bổ sung, đôi khi nó có thể vượt trội hơn các trình biên dịch trước thời hạn và thậm chí (trong trường hợp hiếm hoi) nội tuyến thủ công. So sánh với C / C ++ trong đó các cuộc gọi phương thức đi kèm với một hình phạt hiệu năng nhỏ nếu trình biên dịch quyết định không nội tuyến.

  • Đồng bộ hóa và đa luồng rất dễ dàng và hiệu quả. Java được thiết kế để nhận biết luồng ngay từ đầu và nó cho thấy. Các máy tính hiện đại thường có nhiều lõi và do luồng được tích hợp vào ngôn ngữ, bạn có thể rất dễ dàng tận dụng. Về cơ bản, tăng thêm 100% đến 300% tốc độ so với mã C đơn luồng tiêu chuẩn. Vâng, các luồng và thư viện C được viết cẩn thận có thể đánh bại điều này, nhưng đó là rất nhiều công việc bổ sung cho lập trình viên.

  • Chuỗi bao gồm chiều dài: một số hoạt động nhanh hơn. Nhịp này sử dụng các chuỗi phân cách null (phổ biến trong C). Trong Java 7, Oracle đã loại bỏ tối ưu hóa String.subString (), bởi vì mọi người đang sử dụng nó một cách ngu ngốc và bị rò rỉ bộ nhớ.

  • Sao chép mảng được tối ưu hóa cao. Trong các phiên bản mới nhất, Java sử dụng trình biên dịch được điều chỉnh bằng tay cho System.arraycopy. Kết quả là trong các hoạt động nặng về mảng / bản ghi nhớ, tôi đã thấy mã của mình đánh bại tương đương bằng C bằng các mức hợp lý.

  • Trình biên dịch JIT thông minh về việc sử dụng bộ đệm L1 / L2 . Các chương trình được biên dịch trước thời gian không thể điều chỉnh mã của chúng theo thời gian thực với CPU & hệ thống cụ thể mà chúng đang chạy. JIT cung cấp một số biến đổi vòng lặp rất hiệu quả theo cách này.

Một vài sự thật lịch sử khác góp phần vào danh tiếng "Java là chậm":

  • Trước khi biên dịch JIT (Java 1.2 / 1.3), ngôn ngữ chỉ được diễn giải, không được biên dịch và do đó rất chậm.
  • Quá trình biên dịch JIT cần có thời gian để trở nên hiệu quả (những cải tiến lớn với mỗi phiên bản)
  • Tải lớp đã trở nên hiệu quả hơn rất nhiều trong những năm qua. Nó từng khá kém hiệu quả và chậm trong quá trình khởi động.
  • Mã swing và UI không sử dụng phần cứng đồ họa gốc rất tốt.
  • Xoay chỉ là khủng khiếp. Tôi đổ lỗi cho AWT và Swing về lý do tại sao Java không bao giờ bị bắt cho máy tính để bàn.
  • Sử dụng nhiều đồng bộ hóa trong các lớp thư viện; phiên bản không đồng bộ hiện có sẵn
  • Các ứng dụng sẽ mất mãi mãi để tải, vì truyền JAR đầy đủ qua mạng và tải VM để khởi động.
  • Đồng bộ hóa được sử dụng để thực hiện một hình phạt hiệu năng nặng (điều này đã được tối ưu hóa với mỗi phiên bản Java). Sự phản ánh vẫn còn tốn kém, mặc dù.

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.là những tuyên bố hoang dã không được hỗ trợ bởi bất kỳ bằng chứng nào được liên kết ở đây.
Sjoerd

8
@Sjoerd - Các tuyên bố hầu như không hoang dã - chúng rõ ràng đối với tôi và nên dành cho bất kỳ ai hiểu được sự khác biệt trong kiến ​​trúc của hệ thống bộ nhớ mặc định trong C / C ++ so với Java. Bạn có thể làm tốt hơn nhiều nếu bạn viết trình xử lý bộ nhớ của riêng mình (với những thứ như danh sách miễn phí, nhóm bộ nhớ, v.v.) hoặc sử dụng một thư viện thực hiện như vậy.
Rex Kerr

15
@Rex Kerr - Tại sao nên sử dụng trình xử lý bộ nhớ nếu bạn có thể sử dụng ví dụ: ngăn xếp để phân bổ?! Bạn đang nhầm lẫn phân bổ bộ nhớ heap với khởi tạo đối tượng.
Sjoerd

20
@Rex Kerr - Về cơ bản, bạn cho rằng vì mọi thứ trong Java liên quan đến việc phân bổ bộ nhớ trên heap và vì phân bổ của Java trên heap trong Java nhanh hơn C ++, mọi thứ trong Java đều nhanh hơn. Đây là một số tin tức cho bạn: trong C ++, bạn có thể làm mà không cần phân bổ bộ nhớ trên heap trong nhiều trường hợp!
Sjoerd

10
@Sjoerd - Tôi đã nói rằng mọi thứ trong Java nhanh hơn ở đâu? Chỉ cần đọc những gì tôi nói. Tôi đã nói những gì tôi muốn nói và đã giải quyết tất cả những gì bạn nói trong bình luận cuối cùng của bạn.
Rex Kerr

49

Ban đầu Java không đặc biệt nhanh, nhưng nó cũng không quá chậm. Những ngày này, Java rất nhanh. Từ những người mà tôi đã nói đến ấn tượng về việc Java bị chậm xuất phát từ hai điều:

  1. Thời gian khởi động VM chậm. Việc triển khai Java ban đầu mất nhiều thời gian để khởi động và tải các thư viện và ứng dụng yêu cầu so với các ứng dụng gốc.

  2. Giao diện người dùng chậm. Đu quay sớm đã chậm. Có lẽ điều đó cũng không giúp được rằng hầu hết người dùng Windows đều thấy Metal L & F mặc định xấu xí.

Với những điểm trên, không có gì lạ khi mọi người có ấn tượng 'Java chậm'.

Đối với người dùng hoặc nhà phát triển được sử dụng để phát triển ứng dụng gốc hoặc thậm chí ứng dụng Visual Basic , hai điểm này là điều dễ thấy nhất trong một ứng dụng và đó là ấn tượng đầu tiên bạn sẽ nhận được về một ứng dụng (trừ khi đó là ứng dụng không phải GUI trường hợp chỉ áp dụng 1.).

Bạn sẽ không thuyết phục được người dùng rằng "nó thực thi mã rất nhanh" khi ứng dụng mất 8 giây để khởi động so với ứng dụng Visual Basic cũ của anh ta khởi động ngay lập tức - mặc dù thời gian thực thi mã và khởi động có thể không được kết nối.

Làm hỏng ấn tượng đầu tiên là một cách tuyệt vời để bắt đầu những tin đồn và huyền thoại. Và tin đồn và huyền thoại là khó để giết chết.

Nói tóm lại, Java không chậm. Những người có "Java là thái độ chậm" dựa trên những ấn tượng đầu tiên về Java hơn 10 năm trước.


3
Java đã rất chậm vài năm trước nhưng trong các bài kiểm tra điểm chuẩn gần đây, nó chạy gần như nhanh như C / C ++ và trong một số tình huống, nó chạy nhanh hơn.
ChadNC

23
Các ứng dụng Java trên OSX 10.6 trên Macbook của tôi khởi động chậm hơn nhiều so với các ứng dụng được viết trong Objective-C. Bằng chứng nào cho thời gian khởi động nhanh?
Zan Lynx

2
Giải nén hoàn toàn không phải là một vấn đề hiệu suất. Máy tính của tôi vào năm 1992 đã giải nén các tệp thực thi khi khởi động các chương trình cải thiện hiệu năng qua việc tải một tệp dài hơn từ ổ cứng. Sự chênh lệch giữa CPU và ổ cứng đã tăng lên rất nhiều trong những năm qua. Tuy nhiên, có một vấn đề với việc sử dụng định dạng lưu trữ zip cho rt.jar (tại sao? !!!) và các tệp lớp chứa không được liên kết (các hạt !!).
Tom Hawtin - tackline

5
@Zan: lưu ý rằng JVM cho Mac OS X được viết (hoặc ít nhất là được điều chỉnh) bởi Apple. Sun đã đầu tư khá nhiều thời gian để giúp thời gian khởi động nhanh hơn trên các nền tảng mà họ hỗ trợ (Windows, Linux và Solaris), nhưng họ không thể làm điều đó cho Mac OS x (vì họ không duy trì cổng đó). Có thể là Mac không thể / không áp dụng / chuyển tất cả những tối ưu hóa đó sang Mac OS X.
Joachim Sauer

1
Tôi không coi java là chậm (tôi biết một nhà sản xuất trò chơi tạo ra các trò chơi trong đó); chỉ xấu vì lý do UI. Không một ứng dụng java "thông thường" nào tôi từng thấy có giao diện người dùng hoàn toàn hoạt động tốt.
RCIX

40

Sau khi đọc một trang đầy những bình luận nói rằng Java không chậm, tôi chỉ phải trả lời với một ý kiến ​​khác.

Sự chậm chạp của một ngôn ngữ phụ thuộc rất nhiều vào những gì bạn mong đợi là 'nhanh'. Nếu bạn coi C # là nhanh, thì Java chắc chắn cũng nhanh. Nếu miền vấn đề của bạn liên quan đến cơ sở dữ liệu hoặc xử lý bán thời gian thực, Java chắc chắn cũng đủ nhanh. Nếu bạn vui lòng mở rộng quy mô ứng dụng của mình bằng cách thêm nhiều phần cứng, Java có thể sẽ nhanh cho bạn. Nếu bạn cho rằng việc tăng tốc hệ số không đổi trong thang điểm 5-10 không có giá trị, bạn có thể cân nhắc Java nhanh.

Nếu bạn thực hiện tính toán số trên các tập dữ liệu lớn hoặc bị ràng buộc với môi trường thực thi, nơi tài nguyên CPU bị hạn chế, trong đó tốc độ tăng tốc không đổi trong thang điểm 5-10 sẽ rất lớn. Ngay cả việc tăng tốc 0,5 có thể có nghĩa là giảm 500 giờ để tính toán hoàn tất. Trong những trường hợp này, Java không cho phép bạn đạt được hiệu năng cuối cùng đó và bạn có thể coi Java là chậm.


2
đồng ý và +1 trên toàn bộ bài đăng vì bạn đưa ra một điểm hợp lệ, tuy nhiên, C ++ chẳng hạn có tiếng tăm khó gỡ lỗi và dễ dàng thổi bay toàn bộ chân của bạn, nhưng hiếm khi tôi nghe nói về C ++ bị chậm nhiều như tôi đã nghe về java.
Stefano Borini

33

Có vẻ như bạn đang hỏi hai câu hỏi khá khác nhau:

  1. Là Java thực sự chậm, và nếu vậy tại sao?
  2. Tại sao Java được coi là chậm, mặc dù nó nhanh hơn nhiều lựa chọn thay thế?

Câu hỏi đầu tiên trong số này ít nhiều là một câu hỏi "bao lâu là một sợi dây". Nó đi xuống định nghĩa của bạn về "chậm". So với một trình thông dịch thuần túy, Java cực kỳ nhanh. So với các ngôn ngữ khác (thông thường) được biên dịch theo một loại mã byte nào đó, sau đó được biên dịch động thành mã máy (ví dụ C # hoặc bất cứ thứ gì khác trên .NET) Java gần như ngang bằng. So với các ngôn ngữ thường được biên dịch thành mã máy thuần túy và có các nhóm người (thường là lớn) không làm việc gì ngoài việc cải thiện trình tối ưu hóa của họ (ví dụ: C, C ++, Fortran, Ada) Java khá tốt ở một số điều, nhưng nhìn chung ít nhất có xu hướng chậm hơn một chút.

Rất nhiều thứ liên quan chủ yếu đến việc triển khai - về cơ bản, có một thực tế là người dùng đang chờ trong khi trình biên dịch động / JIT chạy, vì vậy trừ khi bạn có một chương trình chạy khá lâu để bắt đầu, đó là khó để biện minh cho việc trình biên dịch dành nhiều thời gian cho việc tối ưu hóa khó khăn. Do đó, hầu hết các trình biên dịch Java (và C #, v.v.) không đặt nhiều nỗ lực vào việc tối ưu hóa thực sự khó khăn. Trong rất nhiều trường hợp, nó ít hơn về những gì tối ưu hóa được thực hiện, hơn là nơi chúng được áp dụng. Nhiều vấn đề tối ưu hóa đã hoàn tất NP, vì vậy thời gian chúng phát triển nhanh chóng với quy mô của vấn đề bị tấn công. Một cách để giữ thời gian trong lý do là chỉ áp dụng tối ưu hóa cho một cái gì đó giống như một chức năng duy nhất tại một thời điểm. Khi chỉ có nhà phát triển chờ trình biên dịch, bạn có thể đủ khả năng để mất nhiều thời gian hơn và áp dụng tối ưu hóa tương tự cho các phần lớn hơn của chương trình. Tương tự như vậy, mã cho một số tối ưu hóa là khá nhiều lông (và do đó có thể khá lớn). Một lần nữa, vì người dùng đang chờ trong khi tải mã (và thời gian khởi động JVM thường là một yếu tố quan trọng trong thời gian tổng thể), nên việc triển khai phải cân bằng thời gian được lưu ở một nơi so với bị mất ở nơi khác - và cho biết ít mã lợi ích từ việc tối ưu hóa lông, giữ cho JVM nhỏ thường có lợi hơn.

Một vấn đề thứ hai là với Java, bạn thường xuyên nhận được một loại giải pháp "một kích thước phù hợp với tất cả". Ví dụ, đối với nhiều nhà phát triển Java, về cơ bản, thư viện cửa sổ duy nhất có sẵn. Trong một cái gì đó như C ++, có hàng tá thư viện cửa sổ, khung ứng dụng, v.v., mỗi cái có một sự thỏa hiệp riêng giữa dễ sử dụng so với thực thi nhanh, giao diện nhất quán và cảm nhận so với giao diện tự nhiên, v.v. Điểm gắn bó thực sự duy nhất là một số (ví dụ Qt) có thể khá đắt (ít nhất là cho mục đích thương mại).

Thứ ba rất nhiều mã được viết bằng C ++ (và C thậm chí còn hơn thế) đơn giản là cũ hơn và trưởng thành hơn. Rất nhiều trong số đó chứa cốt lõi của các thói quen được viết từ nhiều thập kỷ trước, khi dành thêm thời gian để tối ưu hóa mã là hành vi bình thường, được mong đợi. Điều đó thường có một lợi ích thực sự trong mã đó nhỏ hơn và nhanh hơn. C ++ (hoặc C) nhận được tín dụng cho mã nhỏ và nhanh, nhưng nó thực sự là một sản phẩm của nhà phát triển và các ràng buộc về thời gian mã được viết. Ở một mức độ nào đó, điều này dẫn đến một lời tiên tri tự hoàn thành - khi mọi người quan tâm đến tốc độ, họ thường chọn C ++ vì nó có danh tiếng đó. Họ đặt thêm thời gian và nỗ lực để tối ưu hóa, và một thế hệ mã C ++ nhanh mới được viết.

Tóm lại, việc triển khai Java bình thường khiến tối ưu hóa tối đa có vấn đề. Tồi tệ hơn, nơi Java hiển thị , những thứ như bộ công cụ cửa sổ và thời gian khởi động JVM thường đóng vai trò lớn hơn tốc độ thực thi của chính ngôn ngữ. Trong rất nhiều trường hợp, C và C ++ cũng nhận được tín dụng cho những gì thực sự là sản phẩm của việc đơn giản hóa làm việc chăm chỉ hơn để tối ưu hóa.

Đối với câu hỏi thứ hai, tôi nghĩ phần lớn là vấn đề bản chất của con người trong công việc. Một vài người quá khích đưa ra những tuyên bố khá thổi phồng về việc Java nhanh chóng bị làm mờ. Ai đó thử nó và thấy rằng ngay cả một chương trình tầm thường cũng mất vài giây để bắt đầu, và cảm thấy chậm chạp và vụng về khi nó chạy. Rất ít người có thể bận tâm phân tích mọi thứ để nhận ra rằng phần lớn trong số này là thời gian khởi động của JVM và thực tế là khi họ lần đầu tiên thử mọi thứ, chưa có đoạn mã nào được biên dịch - một số mã đang được diễn giải, và một số được biên dịch trong khi họ chờ đợi. Tồi tệ hơn, ngay cả khi nó chạy đủ nhanh, giao diện thường sẽ có vẻ xa lạ và vụng về với hầu hết người dùng, vì vậy ngay cả khi các phép đo khách quan cho thấy thời gian phản hồi nhanh, nó vẫn có vẻ vụng về.

Thêm những thứ đó lại với nhau dẫn đến một phản ứng khá đơn giản và tự nhiên: Java chậm chạp, xấu xí và vụng về. Với sự cường điệu nói rằng nó thực sự rất nhanh, có xu hướng phản ứng thái quá và kết luận rằng nó chậm đến mức khủng khiếp , thay vì "chậm hơn một chút, và chủ yếu là trong những trường hợp cụ thể." Điều này nói chung là tồi tệ nhất đối với một nhà phát triển viết một vài chương trình đầu tiên bằng ngôn ngữ. Việc thực thi chương trình "hello world" trong hầu hết các ngôn ngữ xuất hiện tức thời, nhưng trong Java có một sự tạm dừng dễ nhận biết khi JVM khởi động. Ngay cả một trình thông dịch thuần túy chạy chậm hơn nhiều trên các vòng lặp chặt chẽ và như vậy vẫn sẽ thường xuất hiện nhanh hơn cho mã như thế này, đơn giản vì nó có thể được tải và bắt đầu thực thi sớm hơn một chút.


16

Đó là thông tin lỗi thời từ những ngày đầu (giữa đến cuối những năm 1990) của Java. Mỗi phiên bản chính của Java đã giới thiệu các bản tăng tốc đáng kể so với phiên bản trước. Với việc Oracle dường như hợp nhất JRockit với JVM của Sun cho Java 7, xu hướng này dường như sẽ tiếp tục.

So với nhiều ngôn ngữ hiện đại phổ biến khác (Python, Ruby, PHP), Java thực sự nhanh hơn đáng kể cho hầu hết các mục đích sử dụng. Nó không hoàn toàn khớp với C hoặc C ++ nhưng đối với nhiều tác vụ, nó đủ gần. Các mối quan tâm về hiệu năng thực sự phải là về việc nó sử dụng bao nhiêu bộ nhớ.


14

Thủ phạm chính trong "thời gian khởi động dài" là liên kết động. Một ứng dụng Java bao gồm các lớp được biên dịch. Mỗi lớp tham chiếu các lớp khác (đối với các kiểu đối số, các cách gọi phương thức ...) theo tên . JVM phải kiểm tra và khớp các tên đó khi khởi động. Nó làm như vậy tăng dần, chỉ làm những phần mà nó cần tại bất kỳ thời điểm nào, nhưng đó vẫn là một số việc phải làm.

Trong một ứng dụng C, pha liên kết đó xảy ra ở cuối quá trình biên dịch. Nó chậm, đặc biệt đối với các ứng dụng lớn, nhưng chỉ nhà phát triển mới nhìn thấy nó. Liên kết mang lại một tệp thực thi mà HĐH đơn giản phải tải trong RAM "như hiện tại".

Trong Java, liên kết xảy ra mỗi khi ứng dụng được chạy. Do đó thời gian khởi động dài.

Nhiều tối ưu hóa khác nhau đã được áp dụng, bao gồm các kỹ thuật lưu trữ và máy tính trở nên nhanh hơn (và chúng "nhanh hơn" so với các ứng dụng "lớn hơn"), do đó, tầm quan trọng của vấn đề đã giảm đi gần đây; nhưng định kiến ​​cũ vẫn còn.

Về hiệu suất sau đó, điểm chuẩn của riêng tôi về các tính toán nhỏ gọn với truy cập mảng (chủ yếu là hàm băm và các thuật toán mã hóa khác) thường cho thấy mã C được tối ưu hóa nhanh hơn khoảng 3 lần so với mã Java; đôi khi C chỉ nhanh hơn 30% so với Java, đôi khi C có thể nhanh hơn gấp 4 lần, tùy thuộc vào thuật toán được triển khai. Tôi đã thấy hệ số 10 lần khi mã "C" thực sự được lắp ráp cho các số nguyên lớn, do các phép nhân 64x64-> 128 mà bộ xử lý cung cấp nhưng Java không thể sử dụng vì loại số nguyên dài nhất của nó là 64 bit long. Đây là một trường hợp cạnh. Trong điều kiện thực tế, việc xem xét băng thông I / O và bộ nhớ ngăn mã C thực sự nhanh hơn ba lần so với Java.


Hmm ... Tôi nghĩ rằng hầu hết các thư viện C ngày nay cũng được liên kết động. Hay bạn đang nói về một cái gì đó khác nhau?
Sean McMillan

4
@Sean: liên kết động cho C xảy ra đối với "các ký hiệu bên ngoài": các hàm được sử dụng trong một DLL và được định nghĩa trong một DLL khác. Một ứng dụng C điển hình sẽ sử dụng một tá DLL. Đối với liên kết động Java xảy ra cho tất cả các phương thức trong tất cả các lớp: có hàng ngàn phương thức trong một ứng dụng Java điển hình (bao gồm cả thư viện chuẩn). Trong thế giới C, hầu hết các liên kết (tất cả các liên kết không vượt qua ranh giới DLL) đều được giải quyết tại thời điểm biên dịch, chỉ một tỷ lệ nhỏ vẫn còn phải làm trong thời gian chạy.
Thomas Pornin

14

Java chắc chắn là chậm, đặc biệt là cho công việc định lượng.

Tôi sử dụng kết hợp R , Python và C / C ++ với các thư viện ATLAS đa luồng được tối ưu hóa . Trong mỗi ngôn ngữ này, tôi có thể nhân ma trận 3000 nhân với 3000 ma trận nhân đôi với chính nó trong khoảng 4 giây. Sử dụng Colt và Parallel Colt trong Java, thao tác tương tự mất 185 giây! Đáng kinh ngạc mặc dù các thư viện java là song song trong tự nhiên.

Vì vậy, tất cả trong tất cả, Java thuần túy là không phù hợp cho công việc định lượng. Jblas dường như là thư viện đại số tuyến tính tốt nhất cho Java vì nó sử dụng ATLAS.

Máy của tôi là HP Core 2 Duo với 3 GB RAM. Tôi sử dụng Ubuntu 10.04 64-bit (Lucid Lynx).


Tiếp theo từ nhận xét đã nói ở trên, tôi đã thực hiện thao tác nhân ma trận tương tự bằng JAMA và mất khoảng 50 giây. Vẫn còn quá chậm so với các ngôn ngữ khác.
Hamaad Shah

7
Java đã mất bao lâu khi bạn thực hiện phép nhân trong các libraires được gọi thông qua JNI. Cho rằng bất cứ điều gì bạn có thể làm trong C / C ++, bạn có thể làm với JNI (thêm vài trăm mnano-giây), biên độ tương đối nhỏ. Tôi đoán phép nhân ma trận R và Python của bạn không được viết bằng R hoặc Python, chỉ được gọi từ các ngôn ngữ đó.
Peter Lawrey

2
Vì tò mò, bạn đã thực hiện bất kỳ hồ sơ nào để xác định xem bạn có một số điểm nóng trong mã của mình không (loại chuyển đổi / hộp thư tự động)?
Thorbjørn Ravn Andersen

10

Đối với hầu hết mọi người trải nghiệm tương tác với nó - Java rất chậm. Chúng ta đều đã thấy rằng cốc cà phê quay xung quanh trên trình duyệt của chúng tôi trước khi một số applet xuất hiện. Phải mất một thời gian để quay JVM và tải xuống các nhị phân applet và điều đó tác động đến trải nghiệm người dùng theo cách được chú ý.

Điều đó không giúp ích gì cho thời gian tải xuống và quay lại JVM chậm được gắn nhãn rõ ràng với cốc cà phê Java, vì vậy mọi người liên kết sự chờ đợi với Java. Khi Flash mất nhiều thời gian để tải, thương hiệu của thông báo "đang tải" được chỉ định bởi nhà phát triển Flash, vì vậy mọi người không đổ lỗi cho toàn bộ công nghệ Flash.

Tất cả những điều này không liên quan gì đến hiệu suất của Java trên máy chủ hoặc theo nhiều cách khác mà Java được sử dụng bên ngoài trình duyệt. Nhưng đó là những gì mọi người nhìn thấy và những gì các nhà phát triển không phải Java nhớ khi họ nghĩ về Java.


9

Java có tiếng là chậm bởi vì nó chậm. Các phiên bản đầu tiên của Java không có hoặc rất kém khi biên dịch Just In Time. Điều này có nghĩa là mã, mặc dù mã byte, đã được giải thích, do đó, ngay cả đối với các hoạt động đơn giản nhất (như thêm hai số nguyên), máy phải thực hiện tất cả các loại so sánh và các lệnh gọi con trỏ và hàm gọi. Trình biên dịch JIT đã được cải tiến không ngừng; bây giờ là lúc tôi viết mã C ++ một cách bất cẩn và mã Java bất cẩn, đôi khi Java sẽ vượt trội hơn C ++ vì trình biên dịch JIT nhận ra rằng tôi đã có một số trình duyệt con trỏ không cần thiết và sẽ chăm sóc nó cho tôi.

Nếu bạn muốn xem phần tổng hợp JIT tạo ra sự khác biệt lớn như thế nào, hãy xem các điểm chuẩn được giải thích so với không được giải thích tại Trò chơi Điểm chuẩn Ngôn ngữ Máy tính . (Pidigits sử dụng một thư viện bên ngoài để thực hiện tất cả các tính toán, do đó, điểm chuẩn không thay đổi; những cái khác hiển thị tốc độ tăng gấp 6-16 lần!)

Vì vậy, đó là lý do chính. Có nhiều lý do khác, ít hơn không giúp ích được gì: ban đầu, thời gian khởi động Java chậm (hiện đã được sửa); các ứng dụng web trong Java mất nhiều thời gian để tải xuống (hiện tại ít đúng với băng thông rộng có thể truy cập rộng rãi và với những thứ lớn như phim được mong đợi); Giao diện người dùng không được viết (và vẫn không) được viết với hiệu suất trong tâm trí vì vậy nó ít linh hoạt hơn nhiều so với tương đương trong ví dụ C ++.


6

Java đã chậm, trở lại trong ngày. Nó đã trở nên nhanh hơn nhiều, do một vài thế hệ cải tiến hiệu suất . Lần cuối tôi nghe, nó thường nằm trong phạm vi 10% tốc độ C # - đôi khi nhanh hơn, đôi khi chậm hơn.

Khởi động applet Java vẫn còn chậm vì bạn phải khởi động toàn bộ JVM, phải tải tất cả các lớp của nó. Hơi giống như khởi động máy tính khác. Khi JVM khởi động, nó khá nhanh, nhưng khởi động thường là những gì mọi người nhớ.

Ngoài ra, có ít nhất một vài người sẽ không bao giờ tin vào khả năng tồn tại của Java.


1
Thật không may, khởi động JVM vẫn chậm hơn nhiều so với khởi động CLR. Điều này là do Sun đã kéo chân theo cách tồi tệ nhất trong việc phát hành Java 7, vì vậy chúng tôi bị mắc kẹt với các bản vá tăng dần cho Java 4 tuổi 6.
BobMcGee

3
Wow, Java 6 đã 4 tuổi ??? Đúng, tôi đoán vậy (nếu bạn tính beta). Vẫn cảm thấy mới đối với tôi - Tôi chỉ dừng sử dụng 1.4 tại nơi làm việc.
Kaleb Brasee

Java 1.4 có thể sử dụng được, nhưng loại này rất hấp dẫn, vì 1.5 và 1.6 đã bổ sung rất nhiều hiệu năng và đường cú pháp. Tối ưu hóa giới hạn kiểm tra và System.arraycopy đã được giới thiệu kể từ đó. Vì vậy, đã có rất nhiều cải tiến đồng bộ hóa. Tôi nghĩ thật công bằng khi nói 1.4 thật sự là chậm.
BobMcGee

LOL, tôi biết - mỗi lần tôi phải lặp lại thủ công hoặc sử dụng một mảng thay vì Danh sách chung, tôi muốn phá vỡ máy tính xách tay của mình một nửa ... IBM thực sự đã có sẵn Java 5 trên WAS 6.1 trong nhiều năm, nhưng tôi đã bị kẹt trên WAS 6.0 :( Tôi đã sử dụng Java 5/6 kể từ khi nó được phát hành cho công cụ của riêng tôi, nhưng chỉ bị giới hạn bởi các phiên bản máy chủ cũ đang hoạt động. Có những cải tiến hiệu suất hai chữ số từ 1.4 đến các phiên bản mới nhất cho rất nhiều thứ, và tôi đang mong chờ chúng.
Kaleb Brasee

6

Stefano:

Tôi đã làm việc với Java từ khi bắt đầu, vì vậy theo quan điểm của tôi, sự nổi tiếng bị chậm được tạo ra bởi các giao diện GUI không phản hồi và chậm (AWT, và sau đó là Swing) và trong Applet có thể do thời gian khởi động chậm thêm của Máy ảo.

Java đã quy định và thúc đẩy rất nhiều nghiên cứu trong khu vực VM và đã có khá nhiều cải tiến, bao gồm cả bộ sưu tập rác (bạn có thể điều chỉnh rất nhiều thứ thực sự; tuy nhiên, tôi thường thấy các hệ thống chỉ sử dụng mặc định) và hotspot tối ưu hóa (lúc đầu và có lẽ vẫn hiệu quả hơn ở phía máy chủ).

Java ở cấp độ phụ trợ và mức độ tính toán không chậm. Colt là một trong những ví dụ tốt nhất:

Bản phát hành Colt ổn định mới nhất phá vỡ rào cản 1.9 Gflop / s trên JDK ibm-1.4.1, RedHat 9.0, 2x IntelXeon@2.8 GHz.

Có nhiều thứ bên ngoài Java chính cần được xem xét, như Java thời gian thực hoặc các cơ chế đặc biệt để tăng cường tốc độ như Javolution , cũng như biên dịch Ahead-Of-Time (như gcj). Ngoài ra, có những IC có thể thực thi Java Bytecode trực tiếp, ví dụ như IC có trong iPhone và iPod Jazelle hiện tại của ARM .

Tôi nghĩ rằng nói chung ngày nay đó là một quyết định chính trị (như không hỗ trợ Java trên iPhone / iPod) và quyết định chống lại Java như một ngôn ngữ (vì nhiều người cho rằng nó quá dài dòng).

Tuy nhiên, hiện nay có nhiều ngôn ngữ khác cho Java VM (ví dụ: Python, Ruby, JavaScript, Groovy, Scala, v.v.) có thể là một ngôn ngữ thay thế.

Cá nhân tôi tiếp tục tận hưởng nó như một nền tảng linh hoạt và đáng tin cậy, với khả năng sẵn có của công cụ và thư viện tuyệt vời, cho phép một người làm việc với mọi thứ từ thiết bị nhỏ nhất (ví dụ JavaCard) đến các máy chủ lớn nhất.


Ok, vậy là một tiếng xấu khác đến từ bộ công cụ GUI. Tất nhiên tôi giả sử rằng, vì JVM hiện đại sử dụng các widget gốc, chúng móc vào các thư viện hệ điều hành, phải không? hoặc họ sử dụng AWT / Swing để hiển thị cùng giao diện của nền tảng máy chủ?
Stefano Borini

Stefano: Swing thực sự dựa trên ý tưởng kết xuất các vật dụng phổ biến không phải bản địa, vì vậy giả định của bạn là loại sai. Đây thực sự là một cơ chế "nhìn và cảm nhận có thể cắm được" cho phép các thành phần Swing mô phỏng sự xuất hiện của các thành phần gốc. Nếu bạn đang tìm kiếm một cái gì đó tương tự, bạn có thể muốn kiểm tra SWT ( eclipse.org/swt ), điều đó thực sự sẽ kết nối với hệ điều hành gốc và sử dụng các widget gốc bằng JNI (được cho là nút cổ chai).
kiêng

Java2D (được sử dụng cho Swing) ngày nay rất nhanh và việc sử dụng các widget gốc (SWT) không mang lại lợi ích hiệu năng. Ít nhất, đó là những gì tôi đọc được khi quyết định học Swing hay SWT 6 tháng trước.
Luigi Plinge

4

Một cái búa chậm hơn nhiều trong việc cán bột hơn nhiều công cụ khác. Không làm cho cái búa "chậm hơn", cũng không hữu ích hơn cho các nhiệm vụ mà nó được thiết kế để thực hiện.

Là một ngôn ngữ lập trình chung, Java ngang hàng với nhiều (nếu không phải hầu hết) cho một loạt các nhiệm vụ lập trình. Có những thử nghiệm cụ thể, tầm thường mà Java sẽ không vượt trội so với các giải pháp được mã hóa bằng tay trong các ngôn ngữ ít phức tạp hơn, những ngôn ngữ "gần với kim loại" hơn.

Nhưng khi nói đến "các ứng dụng trong thế giới thực", Java thường là Công cụ phù hợp. Bây giờ, điều đó nói rằng, không có gì ngăn cản các nhà phát triển thực hiện một giải pháp hiệu suất chậm bằng cách sử dụng công cụ BẤT K .. Lạm dụng công cụ là một vấn đề nổi tiếng (chỉ cần nhìn vào danh tiếng của PHP và VB). Tuy nhiên, cú pháp và thiết kế sạch (chủ yếu) của Java thực hiện rất nhiều để giảm lạm dụng.


3

Java là một ngôn ngữ cấp cao và danh tiếng của nó ngày nay là có hiệu suất ngang bằng với các ngôn ngữ cấp cao khác có thể so sánh được.

  1. Nó có ngữ nghĩa ràng buộc năng động . So với C ++, nơi các phương thức không ảo được biên dịch dưới dạng các hàm gọi, ngay cả trình biên dịch Java tốt nhất trên thế giới cũng phải tạo ra mã kém hiệu quả hơn. Nhưng nó cũng là một ngữ nghĩa cao hơn, sạch hơn.

  2. Tôi không nhớ các chi tiết, nhưng tôi đã nghe trong những ngày đầu của Java rằng có một mutex trên mỗi đối tượng Java, được thu nhận và phát hành bởi mỗi phương thức. Điều đó có xu hướng làm cho nó thích nghi tốt hơn với sự tương tranh, mặc dù không may, chỉ một mutex cho mỗi đối tượng sẽ không bảo vệ bạn khỏi các cuộc đua hoặc bế tắc hoặc bất kỳ điều xấu nào có thể xảy ra trong các chương trình đồng thời. Phần đó, nếu đúng, là một chút ngây thơ, nhưng nó xuất phát từ ý định tốt. Vui lòng điền cho tôi các chi tiết nếu bạn biết thêm về khía cạnh này.

  3. Một cách khác để Java là ngôn ngữ cấp cao là có Bộ sưu tập rác . Garbage-Collection có thể chậm hơn mallocfreecho các chương trình phân bổ cùng một lúc tất cả bộ nhớ họ cần và hoạt động với điều đó. Vấn đề là, trong các ngôn ngữ không có Bộ sưu tập rác, các lập trình viên có xu hướng chỉ viết các chương trình phân bổ tất cả bộ nhớ họ cần cùng một lúc và thất bại nếu nó xuất hiện một số hằng số kích thước tối đa tùy ý đã bị tràn. Vì vậy, so sánh là táo với cam. Khi các lập trình viên nỗ lực viết và gỡ lỗi các chương trình với sự phân bổ động các cấu trúc chuỗi trong các ngôn ngữ không phải là GC, đôi khi họ thấy rằng các chương trình của họ không còn nhanh hơn trong ngôn ngữ GC, bởi vì mallocfreekhông miễn phí Họ cũng có chi phí quá cao ... Ngoài ra, không có lực lượng GC để chỉ định ai giải phóng cái gì và phải chỉ định ai giải phóng cái gì đôi khi buộc bạn tạo bản sao - khi một số chức năng sẽ cần dữ liệu và không rõ là gì sẽ sử dụng nó lần cuối - trong khi việc sao chép sẽ không cần thiết trong ngôn ngữ GC.


1. Có lẽ không đúng với HotSpot. 2. Chỉ khi bạn đánh dấu phương thức là đồng bộ hóa.
Winston Ewert

1
1. Trình biên dịch không tối ưu hóa mã, nhưng JVM đủ thông minh để tự động xác định chỉ một hoặc hai phương thức ảo thường được gọi và có thể gọi chúng một cách tĩnh hoặc thậm chí là nội tuyến chúng. Tôi khá chắc chắn C ++ không thể nội tuyến phương thức ảo. 2. Mọi đối tượng Java đều có khóa. Nó có một chi phí nhỏ (khoảng một byte) trên mỗi đối tượng nhưng ít ảnh hưởng nếu không được sử dụng. 3. Trong Java, bạn có thể phân bổ cùng một lúc tất cả các Đối tượng bạn cần. Điều này có thể cung cấp cho bạn ứng dụng không phải là GC cả ngày. ;) GC của Java hoàn toàn đa luồng, một cái gì đó đòi hỏi sự khao khát đặc biệt trong C ++.
Peter Lawrey

C ++ có thể thực hiện các cuộc gọi ảo nội tuyến, nhưng Java có thể thực hiện nó trong nhiều trường hợp hơn và cũng mạnh hơn với việc tối ưu hóa các trang web cuộc gọi siêu biến dạng.
Piotr Kołaczkowski

2

Vào giữa những năm 1990 khi Java trở thành xu hướng chủ đạo, C ++ là ngôn ngữ chính và web vẫn còn khá mới. Ngoài ra, JVM và GC là những khái niệm tương đối mới trong phát triển chính thống. Các JVM ban đầu khá chậm (so với C ++ chạy trên kim loại trần) và cũng bị tạm dừng đôi khi thu gom rác lâu, dẫn đến tiếng tăm của Java bị chậm.


Đây có phải là do công nghệ đằng sau GC? Tôi biết họ có một số chiến lược (như các lớp thế hệ cho các đối tượng) để hiệu quả hơn trong giai đoạn GC. Chiến lược lúc đó là gì?
Stefano Borini

1
Chuyên gia về JVM của IANA, nhưng tôi nghĩ tại thời điểm đó có một thuật toán quét / đánh dấu luồng đơn được sử dụng cho GC, yêu cầu toàn bộ JVM phải tạm dừng trong khi thực hiện GC. Ngày nay có đánh dấu / quét đồng thời và cũng có nhiều cải tiến hiệu năng khác trong JVM.
Ken Liu

2
Các thuật toán GC hiện đại rất hay nhưng tôi nghĩ rằng cải tiến lớn nhất là JIT.
Pascal Thivent

1

Nhiều ứng dụng máy tính để bàn Java (những thời điểm này: những thứ như Eclipse) có khả năng phản hồi GUI kém, có thể là do mức tiêu thụ bộ nhớ cao và thực tế là trình nạp lớp có thể thực hiện nhiều IO. Nó đang cải thiện nhưng tồi tệ hơn vài năm trước.

Nhiều người (hầu hết) thích thực hiện khái quát hóa nên họ nói "Java chậm" vì họ nhận thấy các ứng dụng chậm khi họ tương tác với chúng.


Bạn có nghĩ rằng mức tiêu thụ bộ nhớ cao đến từ công cụ hoặc từ các thư viện java?
Stefano Borini

Trong trường hợp của Eclipse - từ chính cơ sở hạ tầng Eclipse. Tương tự đối với GUI "nặng" trong quá khứ (JBuilder như tôi nhớ). Tôi có một cảm giác đặc biệt rằng đó là vì cần rất nhiều đối tượng soạn sẵn để sử dụng kiến ​​trúc plugin (như Eclipse) trong một ngôn ngữ được gõ tĩnh. Emacs cũng có các plugin và mức tiêu thụ bộ nhớ của nó ít hơn 10-20 lần so với Eclipse khi thực hiện mã hóa thông thường. Mã Lisp của Emacs được biên dịch thành mã byte và được nạp vào cá thể emacs, sau đó chạy - tương tự như trình nạp lớp Java. Tôi đoán trong Java có hàng tấn các đối tượng trung gian được khởi tạo để cho phép một số khả năng cắm.
Wojciech Kaczmarek

1

Vấn đề chính với các ứng dụng java là nó rất lớn do kích thước lớn của thư viện thời gian chạy chứng khoán. Các chương trình khổng lồ chiếm rất nhiều trong bộ nhớ và có xu hướng hoán đổi, nghĩa là chúng trở nên chậm chạp.

Lý do Sun JVM lớn là vì nó có trình thông dịch mã byte rất tốt, hoạt động bằng cách theo dõi rất nhiều thứ. Điều đó có nghĩa là nhiều dữ liệu, có nghĩa là bộ nhớ.

Bạn có thể muốn xem máy ảo jamvm, một trình thông dịch khá nhanh (không có mã gốc) và rất nhỏ. Nó thậm chí khởi động nhanh.


1

Như Pascal nói, Java ngang hàng với các ngôn ngữ cấp cao khác. Tuy nhiên, như một người đã làm việc với các JVM gốc trên Windows 98 , tại thời điểm mức độ trừu tượng được cung cấp bởi máy ảo Java, chúng ta sẽ thấy đau đớn.

Về cơ bản, đó là phần mềm mô phỏng với rất ít hoặc không có tối ưu hóa mà chúng ta đã được cấp hôm nay trong JVM.


0

Mọi người thường trót lọt dòng "nó diễn giải". Bởi vì đã có một thời, và báo chí xấu được truyền lại bởi những người đã bỏ Java là "quá chậm" và không bao giờ quay lại để thử nghiệm các phiên bản mới hơn.

Hoặc có lẽ "mọi người là những kẻ ngốc" là một câu trả lời tốt hơn.


0

Tôi nghĩ rằng một ngày nào đó, có thể không trong tương lai quá gần, các ngôn ngữ được biên dịch JIT sẽ vượt trội hơn các ngôn ngữ được biên dịch ở bất kỳ khía cạnh nào (tốt, có thể không phải là thời gian khởi động / tiêu thụ bộ nhớ) do trình biên dịch JIT có thể sử dụng nhiều thời gian chạy hành vi và nền tảng họ đang chạy.


6
Tôi nghĩ điều bạn muốn nói là mã do JIT biên dịch (không được giải thích) sẽ đánh bại mã AoT. Phiên dịch sẽ luôn chậm hơn so với chạy mã được biên dịch. Đây là lý do tại sao trình biên dịch JIT được sử dụng. Lưu ý: có rất ít sự khác biệt giữa trình biên dịch trước thời hạn và trình biên dịch JIT về đầu ra, ngoại trừ trình biên dịch JIT phải biên dịch nhanh hơn và có thể sử dụng thông tin thời gian chạy để gợi ý tối ưu hóa. Trình biên dịch AoT dành riêng cho nền tảng với tối ưu hóa dành riêng cho nền tảng hầu như sẽ luôn đánh bại JIT vì không có giới hạn thời gian họ dành cho tối ưu hóa.
BobMcGee

Cảm ơn câu trả lời, không bao giờ nghĩ về các trình biên dịch JIT ít thời gian có sẵn.
trợ giúp

ý bạn là, cái gì đó như tối ưu hóa thích ứng hotspot?
Stefano Borini

2
@BobMcGee: Rất đúng. Một chương trình C ++ có thể được xây dựng để chạy chậm với phản hồi hồ sơ cho tất cả các hoạt động của nó. Sau đó, trình biên dịch có thể tự do xây dựng lại một phiên bản rất nhanh bằng cách sử dụng nửa giờ thời gian CPU và 2 GB RAM. Một JIT đã làm điều này sẽ làm cho người dùng rời đi.
Zan Lynx

1
Thời gian biên dịch JIT không đáng kể đối với các ứng dụng chạy dài như máy chủ. AOT với PGO bị hạn chế hơn so với JIT vì ít nhất 2 lý do. Đầu tiên, hầu hết sự khác biệt hiệu suất đạt được bằng cách tối ưu hóa nhẹ. So sánh gcc -O2 với gcc -O3. Hầu hết thời gian không có sự khác biệt , đôi khi -O3 có thể tốt hơn một chút, đôi khi hơi tệ hơn, nhưng tôi chưa bao giờ trải qua sự khác biệt> 2 lần so với điều này. Thứ hai, sử dụng AOT ngay cả với PGO, bạn chỉ có thể đoán hồ sơ sẽ ở trang sử dụng. Đoán sai, và bạn thua xa JIT. Và hồ sơ thực tế có thể phụ thuộc rất nhiều vào cấu hình.
Piotr Kołaczkowski
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.