Mengapa Python lebih lambat dari Java tetapi lebih cepat dari PHP [ditutup]

17

Saya telah berkali-kali melihat berbagai tolok ukur yang menunjukkan bagaimana sekelompok bahasa melakukan tugas yang diberikan.

Tolok ukur ini selalu mengungkapkan bahwa Python lebih lambat dari Java, dan lebih cepat dari PHP, dan saya bertanya-tanya mengapa demikian.

  • Java, Python, dan PHP dijalankan di dalam mesin virtual
  • Ketiga bahasa mengonversi program mereka menjadi kode byte khusus yang berjalan di atas OS - jadi tidak ada yang berjalan secara native
  • Baik Java dan Python dapat "dikompilasi" ( .pycuntuk Python) tetapi __main__modul untuk Python tidak dikompilasi

Python dan PHP diketik secara dinamis, dan Java secara statis - apakah ini alasan Java lebih cepat, dan jika demikian, tolong jelaskan bagaimana hal itu mempengaruhi kecepatan.

Dan, bahkan jika argumen dinamis-vs-statis benar, ini tidak menjelaskan mengapa PHP lebih lambat dari Python - karena keduanya adalah bahasa yang dinamis.

Anda dapat melihat beberapa tolok ukur di sini dan di sini , dan di sini

treecoder
sumber
Mengenai Python vs PHP: kemungkinan besar hanya masalah kualitas implementasi.
Charles Salvia
8
@good_computer Kebanyakan tolok ukur dilakukan dengan sangat buruk. Ada satu lagi baru-baru ini (saya pikir Anda belum ditautkan) bahwa kebanyakan orang yang mengulasnya mengeluh bahwa bahasa yang diklaimnya "tercepat" hanya memiliki kode optimal terbaik. Ini biasanya dilakukan secara tidak sadar oleh seseorang yang tidak terbiasa dengan bahasa yang akhirnya dianggap "lambat", sehingga mereka tidak menyadari bahwa mereka sedang menulis kode yang lebih baik dalam bahasa yang mereka temukan "cepat".
Izkata
@good_computer Tampaknya bagi saya bahwa Anda mengklaim sesuatu, karena pertanyaan Anda menyertakan teks " Selalu tolok ukur ini mengungkapkan bahwa Python lebih lambat dari Java dan lebih cepat dari PHP " dan " PHP lebih lambat dari Python ". Menghapus kutipan itu dan mengulangi pertanyaan menjadi agnostik bahasa dapat membuatnya dibuka kembali.
pengantin
Pertanyaan ini benar-benar bias : (1) merujuk pada tolok ukur non-otoritatif yang dilakukan pada kode yang sangat tidak dioptimalkan yang naif yang ditulis oleh programmer pemula dalam bahasa yang tidak mereka kuasai (sebagaimana dibedah dalam utas komentar masing-masing) dan (2) dibangun berdasarkan kesalahpahaman. tentang bahasa yang ditafsirkan / bytecode (php / python ditafsirkan, bytecode java, file cache python adalah pohon sintaksis abstrak, bukan bytecode) dan keadaan tiga bahasa (ada versi kompilasi dari kedua python dan php - python lebih matang, dikompilasi php, meskipun, menjalankan facebook)
ZJR

Jawaban:

26

Kode JVM dapat dikompilasi dengan JIT secara efisien, menggunakan kompiler ad hoc yang sepele (dan cepat). Tetapi hal yang sama akan sangat sulit untuk PHP dan Python, karena sifat mereka yang diketik secara dinamis. JVM diterjemahkan ke tingkat asli yang cukup rendah dan kode asli, sangat mirip dengan apa yang dihasilkan kompiler C ++, tetapi untuk bahasa dinamis Anda harus menghasilkan pengiriman dinamis untuk semua operasi dasar dan untuk semua pemanggilan metode. Pengiriman dinamis ini adalah hambatan utama untuk semua bahasa semacam ini.

Dalam beberapa kasus dimungkinkan untuk menghilangkan pengiriman dinamis (serta panggilan virtual di Jawa) menggunakan kompiler JIT tracing jauh lebih rumit. Pendekatan ini masih dalam tahap awal, tidak melakukan terlalu banyak interpretasi abstrak, dan kompiler seperti itu kemungkinan akan tersedak evalpanggilan (yang sangat khas untuk bahasa dinamis).

Adapun perbedaan antara Python dan PHP, yang terakhir hanya kualitas yang jauh lebih rendah. Secara teori bisa berjalan lebih cepat, tetapi tidak akan pernah.

Logika SK
sumber
1
Mengapa JIT "luar biasa" sulit untuk bahasa dinamis? Lihatlah v8 atau TraceMonkey di dunia JavaScript - JIT berfungsi dengan baik.
treecoder
6
@Good_computer, melacak JIT jauh lebih kompleks dari biasanya, JIT ad hoc, dan mereka masih melakukan jauh lebih lambat daripada JIT untuk bahasa yang diketik secara statis. JIT tracing yang tepat akan melibatkan interpretasi abstrak full-blown, dan itu akan mencekik setiap evalpanggilan.
SK-logic
2
Mungkin ada sekitar seratus insinyur di dalam tim penyusun HotSpot Oracle yang tidak setuju tentang bagian "sepele" :-)
Jörg W Mittag
1
@ JörgWMittag, tentu saja, HotSpot tidak sesederhana itu, ia melakukan sedikit analisis statis, ia menggunakan hasil profil runtime, tetapi masih jauh lebih sederhana daripada JIT tracing yang tepat. Dan, saya katakan, HotSpot terlalu rumit dan implementasinya adalah, dengan sopan, sedikit terlalu bertele-tele.
SK-logic
1
@ Frank Shearar, JIT ad hoc untuk bahasa yang dinamis sama sepele dengan yang diketik secara statis (lihat LuaJIT misalnya). OTOH, JIT yang efisien adalah hal yang sangat berbeda.
SK-logic
21

Ada masalah umum dengan pertanyaan ini karena terlalu absolut. Tidak masuk akal untuk mengatakan "bahasa X lebih cepat dari bahasa Y". Bahasa komputer itu sendiri tidak "cepat" atau "lambat" karena itu hanya cara mengekspresikan suatu algoritma. Pertanyaan aktual seharusnya ada pada urutan "mengapa implementasi X1 bahasa X lebih cepat dari implementasi Y1 bahasa Y untuk domain masalah khusus ini?"

Beberapa perbedaan kecepatan pasti akan keluar dari bahasa itu sendiri karena bahasa tertentu lebih mudah untuk mengimplementasikan domain tertentu daripada yang lain. Tetapi banyak dari apa yang membuat implementasi cepat bukan bahasa. Misalnya, Anda tidak bisa mengatakan "Python lebih lambat dari Java" tanpa mempertimbangkan apakah Anda berbicara tentang CPython, IronPython, atau PyPy. Hal ini terutama berlaku untuk bahasa yang menggunakan VM karena kecepatannya akan langsung dipengaruhi oleh kualitas VM.

Selain itu, saya bekerja dengan sistem yang karena berbagai alasan tidak dapat menggunakan JIT pada perangkat kami dengan JavaScript VM yang sangat populer yang biasanya mendukungnya. Ini berarti bahwa JavaScript kami berjalan jauh, jauh lebih lambat daripada di PC dengan prosesor yang sama. Satu perubahan itu, yang tidak terkait langsung dengan bahasa itu sendiri, menjadikan JavaScript dari "beberapa kali lebih lambat daripada C ++" menjadi "pesanan dengan magnitudo lebih lambat dari pada C ++" untuk tugas-tugas yang kita pedulikan.

Juga pertimbangkan adalah bahwa bahasa berbeda dalam karakteristik kinerja dengan cara yang tidak dapat dibandingkan secara langsung. Terlalu banyak tolok ukur hanya menerjemahkan program dari bahasa A ke bahasa B dan tidak memperhitungkan bahwa bahasa berbeda dalam fitur apa yang cepat. (Anda dapat melihat ini dalam perbandingan tolok ukur yang masuk akal seperti yang Anda tautkan karena mereka sering memiliki catatan seperti "terima kasih kepada anu-anu karena menunjukkan kepada saya bagaimana menerapkannya dalam bahasa Foo.)

Misalnya, Ambil kode Java ini:

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

Akan tergoda untuk "menulis ulang" ini dalam C ++ dan membandingkan run time:

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

Masalahnya, setiap programmer C ++ yang kompeten akan segera melihat bahwa di C ++, ini bukan cara tercepat untuk melakukan sesuatu. Anda dapat dengan mudah mempercepat dengan mengubahnya agar lebih sesuai dengan C ++:

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

Intinya bukan bahwa C ++ bisa cepat tetapi daripada menulis tolok ukur untuk membandingkan bahasa benar-benar sulit. Untuk melakukannya dengan tepat, Anda harus menjadi ahli dalam kedua bahasa, dan menulis dari awal dalam kedua bahasa. Bahkan kemudian, Anda dapat dengan mudah lari ke area di mana satu bahasa unggul dalam tugas tertentu. Sebagai contoh, saya dapat menulis versi Towers of Hanoi di C ++ yang akan berjalan lebih cepat dari Java pada kompiler yang masuk akal. Saya bisa melakukannya dengan cara curang, menggunakan templat C ++, dievaluasi pada waktu kompilasi (http://forums.devshed.com/c-programming-42/c-towers-of-hanoi-using-templates-424148.html)

Intinya tidak ada yang bisa saya katakan bahwa "C ++ lebih cepat daripada Java" karena program saya kembali secara instan sementara versi Java berjalan selama beberapa menit (dan berharap tidak ada yang memperhatikan program saya membutuhkan waktu setengah jam untuk membangun.) Intinya adalah bahwa untuk ini bervariasi kasus sempit, C ++ lebih cepat. Untuk kasus sempit lainnya, mungkin sebaliknya. Jadi itu bukan "C ++ lebih cepat", itu "C ++ lebih cepat dalam kasus di mana Anda dapat mengevaluasi ekspresi saat membangun menggunakan templat." Kurang memuaskan, tetapi benar.

Perbedaan kecepatan dalam bahasa sebagian besar tentang implementasi. Bahasa yang dikompilasi akan lebih cepat daripada bahasa yang ditafsirkan. Kompilasi ke kode asli akan lebih cepat daripada kompilasi ke kode byte. Ini akan memiliki lebih banyak efek daripada pertanyaan seperti apakah bahasa diketik secara statis atau tidak. Dan tentu saja, implementasi yang baik akan lebih cepat daripada yang buruk.

Dan jangan lupa bahwa programmer yang baik akan menghasilkan kode yang lebih cepat daripada programmer yang buruk, seringkali sampai pada taraf yang jauh melebihi perbedaan bahasa.

Gort the Robot
sumber
6

Ini berkaitan dengan kualitas kompiler, kompiler java telah terus dioptimalkan lebih lama, dan optimasi lebih penting karena semua kode dikompilasi untuk Java. Saya tidak yakin alasan pasti mengapa python lebih cepat dari PHP, tapi saya berani bertaruh ini karena pengaruh Google dengan Python.

Ryathal
sumber
8
Mengapa ini diturunkan? Ini adalah persis jawabannya: kinerja adalah murni masalah penelitian dan rekayasa usaha, dan dengan demikian pada akhirnya uang. Perusahaan-perusahaan yang menghasilkan implementasi Java kebetulan lebih kaya daripada yang memproduksi implementasi Python atau PHP. Itu saja.
Jörg W Mittag
1
Selain itu, saya cukup yakin optimasi CPython tidak diterima jika mereka membuat kode terlalu sulit untuk dibaca dan hanya meningkatkan kinerja dengan sangat sedikit.
cgt
2
+ Jörg W Mittag: Saya tidak setuju. Beberapa fitur bahasa bisa sangat sulit untuk diimplementasikan secara performansi, oleh karena itu mereka membuat pembuatan implementasi yang efisien menjadi sangat sulit atau hampir tidak mungkin. Di sisi lain, itu mudah untuk membuat implementasi bahasa "Assembler" yang "efisien".
user281377
@ammoQ Saya menduga bahwa banyak dari yang datang untuk mengetikkan sistem dan khususnya untuk mengetahui jenis persis apa yang Anda punya dan apa semantik yang tepat dari operasi yang diizinkan. Bahasa dinamis mendapatkan fleksibilitas dari sifatnya, tetapi membuatnya lebih sulit untuk melakukan pembuktian jenis (dan karenanya mengkompilasi ke kode hyper-fast safe).
Donal Fellows
1
@DonalFellows Persis menurut saya. Semakin sedikit yang diketahui pada waktu kompilasi, semakin banyak yang harus diketahui saat runtime.
user281377
4

Mengapa Java adalah yang tercepat:

Ketikan + JIT kompilasi secara statis + --server flag untuk secara agresif mengkompilasi ulang kode yang sedang berjalan.

Mengapa Python lebih cepat dari PHP:

Python mungkin merupakan bahasa yang dinamis, tetapi masih diketik dengan kuat. Ini berarti bahwa struktur kode Anda mampu optimasi runtime.

Mengapa PHP payah:

Ini pada dasarnya javascript di server (tidak ada dukungan multithreading, benar-benar dinamis, diketik longgar).

Intinya, semakin banyak kompiler tahu tentang kode Anda, semakin banyak yang bisa dioptimalkan. Java sepenuhnya dapat dioptimalkan sebelum dijalankan, dan saat sedang berjalan. Python dapat dioptimalkan saat sedang berjalan, dan PHP, yah, mengerikan. Facebook benar-benar mentranspilasikan PHP mereka ke C sebelum sampai di server.
https://developers.facebook.com/blog/post/2010/02/02/hiphop-for-php--move-fast/

Ajax
sumber
Sebenarnya javascript di server adalah Node.JS dan dari apa yang saya mengerti (meskipun saya tidak akan membuktikan ini) mesin V8 mengungguli PHP secara umum (meskipun mungkin tidak dengan satu ton). Lebih lanjut Anda harus menyebutkan Python dapat dikompilasi ke asli (Bagaimana performanya dibandingkan dengan Java?)
Jimmy Hoffa
Saya belum menggunakan python secara luas untuk membantu Anda di sana, tetapi saya dapat mengatakan bahwa nodejs yang menjalankan V8 memiliki dukungan untuk ekstensi C asli (meskipun melewati batas JS / C seharusnya lambat), ditambah lagi ia dapat mengambil keuntungan dari kompiler JIT Google. .. Saya tidak akan terkejut jika simpul lebih cepat dari pada python dan php. Berikut ini adalah patokan (cacat seperti kebanyakan) blog.famzah.net/2010/07/01/... Perhatikan bahwa java tampak lebih lambat dari JS sampai komentator menunjukkan kelemahan kami pada patokan ... Jadi, bawa dengan sebutir butir garam. :)
Ajax
Yang mengatakan, node dan php juga sama-sama singlethreaded, dan kecuali Anda suka mengatur proxy cluster (seperti haproxy), saya tidak akan menyentuh salah satu dari mereka dalam lingkungan produksi yang serius.
Ajax
1

Tolok ukurnya agak condong mendukung pemrograman matematika yang berat.

Tidak mengherankan bahwa Python cukup bagus dalam matematika yang rumit jika Anda mempertimbangkan di mana dan mengapa itu pertama kali ditulis .

PHP di sisi lain ditulis untuk melayani halaman web, ia dapat melakukan hal-hal lain tetapi halaman web adalah yang terbaik dan setara atau lebih baik daripada Java pada tugas ini.

James Anderson
sumber