Tại sao Python chậm hơn Java nhưng nhanh hơn PHP [đã đóng]


17

Tôi đã nhiều lần thấy các điểm chuẩn khác nhau cho thấy cách một loạt các ngôn ngữ thực hiện trên một nhiệm vụ nhất định.

Các điểm chuẩn này luôn tiết lộ rằng Python chậm hơn Java và nhanh hơn PHP và tôi tự hỏi tại sao lại như vậy.

  • Java, Python và PHP chạy bên trong một máy ảo
  • Tất cả ba ngôn ngữ đều chuyển đổi chương trình của họ thành mã byte tùy chỉnh chạy trên hệ điều hành - vì vậy không có ngôn ngữ nào đang chạy tự nhiên
  • Cả Java và Python đều có thể được "biên dịch" ( .pycđối với Python) nhưng __main__mô-đun cho Python không được biên dịch

Python và PHP được gõ động và Java tĩnh - đây có phải là lý do Java nhanh hơn không và nếu có, vui lòng giải thích điều đó ảnh hưởng đến tốc độ như thế nào.

Và, ngay cả khi đối số động-vs-tĩnh là chính xác, điều này không giải thích tại sao PHP chậm hơn Python - vì cả hai đều là ngôn ngữ động.

Bạn có thể thấy một số điểm chuẩn ở đâyđây , và ở đây


Về Python so với PHP: rất có thể đó chỉ là vấn đề chất lượng triển khai.
Charles Salvia

8
@good_computer Hầu hết các điểm chuẩn được thực hiện rất tệ. Có một cái khác gần đây (tôi không nghĩ rằng bạn đã liên kết) rằng hầu hết những người đã xem xét nó phàn nàn rằng ngôn ngữ mà họ tuyên bố là "nhanh nhất" chỉ đơn giản là có mã được tối ưu hóa tốt nhất. Điều này thường được thực hiện một cách vô thức bởi một người không quen thuộc với các ngôn ngữ được coi là "chậm", vì vậy họ không nhận ra họ đang viết mã tốt hơn trong những ngôn ngữ mà họ thấy là "nhanh".
Izkata

@good_computer Dường như với tôi rằng bạn đang yêu cầu một cái gì đó, vì câu hỏi của bạn bao gồm dòng chữ " Luôn luôn các điểm chuẩn này tiết lộ rằng Python chậm hơn Java và nhanh hơn PHP " và " PHP chậm hơn Python ". Loại bỏ những trích dẫn đó và đọc lại câu hỏi để trở thành bất khả tri ngôn ngữ có thể khiến nó được mở lại.
briddums

Câu hỏi này thực sự sai lệch : (1) đề cập đến các điểm chuẩn không có thẩm quyền được thực hiện trên mã không được tối ưu hóa rất ngây thơ được viết bởi các lập trình viên mới làm quen với các ngôn ngữ mà họ không thành thạo (như được mổ xẻ trong các luồng nhận xét tương ứng) và (2) được xây dựng dựa trên những quan niệm sai lầm về giải thích / ngôn ngữ bytecode (php / python được giải thích, bytecoded, python file cache của java là cây trừu tượng cú pháp, không bytecode) và tình trạng của ba ngôn ngữ (có được biên dịch các phiên bản của cả hai python và php - python được trưởng thành hơn, biên soạn Tuy nhiên, php chạy facebook)
ZJR

Câu trả lời:


26

Mã JVM có thể được biên dịch JIT một cách hiệu quả, sử dụng trình biên dịch ad hoc tầm thường (và nhanh). Nhưng điều tương tự sẽ cực kỳ khó đối với PHP và Python, vì bản chất được gõ động của chúng. JVM chuyển sang một mã gốc khá thấp và đơn giản, khá giống với trình biên dịch C ++ sẽ tạo ra, nhưng đối với các ngôn ngữ động, bạn phải tạo công văn động cho tất cả các hoạt động cơ bản và cho tất cả các lệnh gọi phương thức. Công văn động này là nút cổ chai chính cho tất cả các ngôn ngữ thuộc loại này.

Trong một số trường hợp, có thể loại bỏ công văn động (cũng như các cuộc gọi ảo trong Java) bằng trình biên dịch JIT truy tìm phức tạp hơn nhiều. Cách tiếp cận này vẫn còn ở giai đoạn sơ khai, không thực hiện quá nhiều cách hiểu trừu tượng và trình biên dịch như vậy có khả năng gây nghẹt thở cho evalcác cuộc gọi (rất điển hình cho các ngôn ngữ động).

Đối với sự khác biệt giữa Python và PHP, cái sau có chất lượng thấp hơn nhiều. Nó có thể chạy nhanh hơn trong lý thuyết, nhưng nó sẽ không bao giờ.


1
Tại sao JIT "đặc biệt" khó đối với các ngôn ngữ động? Nhìn vào v8 hoặc TraceMonkey trong thế giới JavaScript - có JIT hoạt động tốt.
Treecoder

6
@good_computer, truy tìm các JIT phức tạp hơn đáng kể so với JIT thông thường, và chúng vẫn hoạt động chậm hơn nhiều so với JIT cho các ngôn ngữ được nhập tĩnh. Một JIT truy tìm thích hợp sẽ liên quan đến một diễn giải trừu tượng toàn diện, và nó sẽ bóp nghẹt từng evalcuộc gọi.
SK-logic

2
Có lẽ có khoảng một trăm kỹ sư trong nhóm trình biên dịch HotSpot của Oracle sẽ không đồng ý về phần "tầm thường" :-)
Jörg W Mittag

1
@ JörgWMittag, tất nhiên, HotSpot không đơn giản như vậy, nó có một chút phân tích tĩnh, nó đang sử dụng các kết quả định hình thời gian chạy, nhưng vẫn đơn giản hơn nhiều so với JIT truy tìm đúng. Và, tôi muốn nói, HotSpot quá phức tạp và việc thực hiện nó là, nói một cách lịch sự, hơi quá dài dòng.
SK-logic

1
@Frank Shearar, một JIT ad hoc cho một ngôn ngữ động cũng tầm thường như đối với một ngôn ngữ được gõ tĩnh (ví dụ, xem LuaJIT). OTOH, một JIT hiệu quả là một điều hoàn toàn khác.
SK-logic

21

Có một vấn đề chung với câu hỏi này là nó quá tuyệt đối. Thật không có nghĩa gì khi nói "ngôn ngữ X nhanh hơn ngôn ngữ Y". Bản thân một ngôn ngữ máy tính không "nhanh" hay "chậm" vì đó chỉ là cách thể hiện một thuật toán. Câu hỏi thực tế phải là một cái gì đó theo thứ tự "tại sao việc triển khai X1 của ngôn ngữ X nhanh hơn thực hiện Y1 của ngôn ngữ Y cho miền vấn đề cụ thể này?"

Một số khác biệt về tốc độ chắc chắn sẽ rơi ra khỏi ngôn ngữ vì các ngôn ngữ nhất định dễ thực hiện một số miền nhất định hơn các ngôn ngữ khác. Nhưng phần lớn những gì làm cho việc thực hiện nhanh không phải là ngôn ngữ. Chẳng hạn, bạn thực sự không thể nói "Python chậm hơn Java" mà không xem xét liệu bạn đang nói về CPython, IronPython hay PyPy. Điều này đặc biệt đúng đối với các ngôn ngữ sử dụng VM vì tốc độ sẽ bị ảnh hưởng trực tiếp bởi chất lượng của VM.

Bên cạnh đó, tôi làm việc với một hệ thống vì nhiều lý do không thể sử dụng JIT trên thiết bị của chúng tôi với máy ảo JavaScript rất phổ biến thường hỗ trợ nó. Điều này có nghĩa là JavaScript của chúng tôi chạy rất xa, chậm hơn nhiều so với trên PC có bộ xử lý tương tự. Một thay đổi đó, không liên quan trực tiếp đến chính ngôn ngữ, đưa JavaScript từ "chậm hơn vài lần so với C ++" thành "các lệnh có cường độ chậm hơn C ++" cho các nhiệm vụ chúng ta quan tâm.

Cũng xem xét là các ngôn ngữ khác nhau về đặc điểm hiệu suất theo những cách không thể so sánh trực tiếp. Quá nhiều điểm chuẩn chỉ cần dịch một chương trình từ ngôn ngữ A sang ngôn ngữ B và không tính đến việc ngôn ngữ khác nhau về những tính năng nhanh. .

Ví dụ: Lấy mã Java này:

for(int i=0;i<10;i++) {
    Object o = new Object;
    doSomething(o);
}

Sẽ rất hấp dẫn khi "viết lại" điều này trong C ++ và so sánh thời gian chạy:

for(int i=0;i<10;i++) {
    Object *o = new Object;
    doSomething(o);
    delete(o);
}

Vấn đề là, bất kỳ lập trình viên C ++ có thẩm quyền nào cũng sẽ thấy ngay rằng trong C ++, đây không phải là cách nhanh nhất để làm điều gì đó. Bạn có thể dễ dàng tăng tốc mọi thứ bằng cách thay đổi nó để phù hợp hơn với C ++:

for(int i=0;i<10;i++) {
    Object o;
    doSomething(&o);
}

Vấn đề không phải là C ++ có thể nhanh mà là viết điểm chuẩn để so sánh các ngôn ngữ thực sự rất khó. Để làm điều đó một cách thích hợp, bạn phải là một chuyên gia trong cả hai ngôn ngữ và viết từ đầu bằng cả hai ngôn ngữ. Thậm chí sau đó, bạn có thể dễ dàng chạy vào các khu vực nơi một ngôn ngữ vượt trội trong một nhiệm vụ cụ thể. Ví dụ: tôi có thể viết một phiên bản Towers of Hanoi bằng C ++ sẽ chạy nhanh hơn Java trên bất kỳ trình biên dịch hợp lý nào. Tôi có thể làm điều đó bằng cách gian lận, bằng cách sử dụng các mẫu C ++, được đánh giá tại thời điểm biên dịch (http://forums.devshed.com/c-programming-42/c-towers-of-hanoi-USE-temsheet-424148.html)

Vấn đề là tôi không thể nói rằng "C ++ nhanh hơn Java" bởi vì chương trình của tôi đã quay lại ngay lập tức trong khi phiên bản Java chạy trong vài phút (và hy vọng không ai nhận thấy chương trình của tôi mất nửa giờ để xây dựng.) trường hợp hẹp khác nhau, C ++ là nhanh hơn. Đối với các trường hợp hẹp khác, nó có thể là cách khác. Vì vậy, nó không phải là "C ++ nhanh hơn", mà là "C ++ nhanh hơn trong các trường hợp bạn có thể đánh giá biểu thức khi xây dựng bằng cách sử dụng các mẫu". Ít thỏa mãn, nhưng đúng.

Sự khác biệt về tốc độ trong các ngôn ngữ chủ yếu là về việc thực hiện. Ngôn ngữ biên dịch sẽ nhanh hơn ngôn ngữ được dịch. Biên dịch thành mã gốc sẽ nhanh hơn biên dịch thành mã byte. Điều này sẽ có tác dụng hơn nhiều so với các câu hỏi như liệu ngôn ngữ có được gõ tĩnh hay không. Và tất nhiên, việc triển khai tốt sẽ nhanh hơn những điều xấu.

Và đừng quên rằng các lập trình viên giỏi sẽ tạo ra mã nhanh hơn các lập trình viên xấu, thường đến một mức độ khá lớn hơn sự khác biệt về ngôn ngữ.


6

Nó liên quan đến chất lượng của trình biên dịch, trình biên dịch của java đã được liên tục tối ưu hóa lâu hơn nhiều và tối ưu hóa là quan trọng hơn vì tất cả các mã được biên dịch cho Java. Tôi không chắc lý do chính xác khiến python nhanh hơn PHP, nhưng tôi sẽ đặt cược vì ảnh hưởng của Google với Python.


8
Tại sao điều này bị hạ thấp? Đây chính xác là câu trả lời: hiệu suất hoàn toàn là vấn đề của nỗ lực nghiên cứu và kỹ thuật, và cuối cùng là tiền. Các công ty sản xuất các triển khai Java thực sự giàu hơn các công ty sản xuất các triển khai Python hoặc PHP. Đó là tất cả.
Jörg W Mittag

1
Hơn nữa, tôi khá chắc chắn rằng tối ưu hóa CPython không được chấp nhận nếu chúng làm cho mã quá khó đọc và chỉ tăng cường hiệu suất rất ít.
cgt

2
+ Jörg W Mittag: Tôi không đồng ý. Một số tính năng ngôn ngữ có thể rất khó thực hiện một cách hiệu quả, do đó chúng làm cho việc tạo ra một triển khai hiệu quả trở nên rất khó khăn hoặc không thể thực hiện được. Mặt khác, thật dễ dàng để tạo ra một triển khai "hiệu quả" của ngôn ngữ "Trình biên dịch".
user281377

@ammoQ Tôi nghi ngờ rằng có rất nhiều trong số đó thuộc về các hệ thống và đặc biệt là khả năng biết chính xác loại bạn đã có và ngữ nghĩa chính xác của các hoạt động được phép là gì. Các ngôn ngữ động có được tính linh hoạt từ bản chất của chúng, nhưng làm cho việc thực hiện các bằng chứng loại khó hơn (và do đó để biên dịch thành mã siêu nhanh an toàn).
Donal Fellows

1
@DonalFellows Chính xác là suy nghĩ của tôi. Càng ít được biết đến tại thời gian biên dịch, càng phải tìm ra nhiều hơn trong thời gian chạy.
user281377

4

Tại sao Java là nhanh nhất:

Gõ tĩnh + biên dịch JIT + cờ máy chủ để biên dịch lại mã đang chạy.

Tại sao Python nhanh hơn PHP:

Python có thể là một ngôn ngữ động, nhưng nó vẫn được gõ mạnh. Điều này có nghĩa là các cấu trúc bạn mã có khả năng tối ưu hóa thời gian chạy.

Tại sao PHP hút:

Về cơ bản, nó là javascript trên máy chủ (không hỗ trợ đa luồng, hoàn toàn năng động, được gõ lỏng lẻo).

Về bản chất, trình biên dịch càng biết nhiều về mã của bạn, nó càng có thể tối ưu hóa. Java hoàn toàn tối ưu hóa trước khi chạy và trong khi nó đang chạy. Python là tối ưu hóa trong khi nó đang chạy, và PHP, tốt, khủng khiếp. Facebook thực sự đã dịch mã PHP của họ sang C trước khi nó vào máy chủ.
https://developers.facebook.com/blog/post/2010/02/02/hiphop-for-php--move-fast/


Trên thực tế, javascript trên máy chủ là Node.JS và từ những gì tôi hiểu (mặc dù tôi sẽ không chứng minh điều này), công cụ V8 vượt trội so với PHP nói chung (mặc dù có lẽ không phải bằng một tấn). Hơn nữa, bạn nên đề cập đến Python có thể được biên dịch thành bản địa (Nó hoạt động như thế nào so với Java sau đó?)
Jimmy Hoffa

Tôi chưa sử dụng python đủ rộng để giúp bạn ở đó, nhưng tôi có thể nói rằng nodejs chạy V8 có hỗ trợ các tiện ích mở rộng C gốc (mặc dù việc vượt qua ranh giới JS / C được cho là chậm), ngoài ra nó có thể tận dụng trình biên dịch JIT của Google. .. Tôi sẽ không ngạc nhiên nếu nút nhanh hơn cả python và php. Đây là một điểm chuẩn (thiếu sót như hầu hết) blog.famzah.net / 2010/07/01 / Lưu ý rằng java trông chậm hơn so với JS cho đến khi một người bình luận chỉ ra sai sót của chúng tôi trong điểm chuẩn ... Vì vậy, hãy lấy nó bằng một hạt Muối. :)
Ajax

Điều đó nói rằng, nút và php cũng đều được đọc đơn và trừ khi bạn thích thiết lập các proxy cụm (như haproxy), tôi sẽ không chạm vào một trong số chúng trong môi trường sản xuất nghiêm túc.
Ajax

1

Các điểm chuẩn khá sai lệch nghiêng về lập trình toán học nặng.

Không có gì đáng ngạc nhiên khi Python khá giỏi toán phức tạp nếu bạn xem xét nơi và lý do nó được viết lần đầu tiên .

PHP trên Mặt khác đã được viết để phục vụ các trang web, nó có thể làm những việc khác nhưng các trang web là những gì tốt nhất của mình tại và nó ngang hoặc tốt hơn so với Java ở nhiệm vụ này.

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.