Seberapa cepat Go bisa pergi?

39

Go adalah salah satu dari beberapa bahasa yang seharusnya menjalankan 'close to the metal', yaitu dikompilasi, diketik secara statis, dan mengeksekusi kode secara native, tanpa VM. Ini harus memberikan keunggulan kecepatan di atas Java, C # dan sejenisnya. Namun, tampaknya itu berada di belakang Java (lihat Program Shootout Language )

Saya berasumsi bahwa kompiler yang kurang matang sangat bertanggung jawab untuk ini, tetapi apakah ada alasan lain? Apakah ada sesuatu yang melekat dalam desain Go yang akan mencegahnya berjalan lebih cepat daripada, katakanlah, Java? Saya memiliki pandangan yang sangat canggih tentang model runtime, tetapi tampaknya setidaknya pada prinsipnya harus dapat berjalan lebih cepat daripada Java, berkat eksekusi kode asli.

Greg Slodkowicz
sumber
3
Mengingat kompiler yang cukup pintar (dan / atau VM, dan / atau kompiler JIT), bahasa yang diberikan selalu dapat berjalan lebih cepat (well, ada keterbatasan fisik, tetapi hanya itu). Benar ini tentu saja tidak membantu siapa pun asalkan kompiler yang cukup pintar ini tidak ada. Perhatikan bahwa Java sudah memiliki implementasi yang cukup pintar, dan mereka sangat pintar. Fakta lain dari kehidupan adalah bahwa menjalankan kode setidaknya memiliki banyak pengaruh pada kinerja runtime sebagai implementasi.
1
Saya mengerti itu, tapi saya bertanya-tanya apakah masuk akal untuk mengharapkan kecepatan Go untuk mencocokkan / menyalip misalnya Java karena kompilernya sudah matang.
Greg Slodkowicz
17
Bahasa pemrograman tidak memiliki kecepatan. Implementasi bahasa juga tidak. Implementasi bahasa yang diberikan memiliki kecepatan untuk beberapa input yang diberikan, dan kecepatan ini dapat sangat tergantung pada input.
8
Membangunkan saya .. sebelum Anda pergi pergi ... WHAM! . Maaf, saya tidak bisa menolak. Di sini datang bendera .. di sini datang bendera ..
Tim Post
2
@delnan - Atau hanya jauh lebih mudah untuk mengatakan "Java" daripada mengatakan "Java (TM) SE Runtime Environment (build 1.6.0_25-b06) Java HotSpot (TM) 64-Bit Server VM (build 20.0-b11 , mode campuran) ":-)
igouy

Jawaban:

46

Dalam hal desain bahasa, sebenarnya tidak ada apa pun yang membuat Go lebih lambat daripada Java pada umumnya. Bahkan, itu memberi Anda lebih banyak kontrol tata letak memori struktur data Anda, jadi untuk banyak tugas umum itu harus agak lebih cepat. Namun, kompiler Go primer saat ini, penjadwal, pengumpul sampah, perpustakaan regexp, dan banyak hal lainnya tidak terlalu dioptimalkan. Ini terus membaik, tetapi fokusnya tampaknya bermanfaat, sederhana, dan cukup cepat daripada menang di microbenchmark.

Dalam tolok ukur tertaut, Go kehilangan besar ke Jawa pada pohon biner dan tes regexp. Itu adalah tes dari sistem manajemen memori dan perpustakaan regexp masing-masing. Manajemen memori Go dapat lebih cepat dan tentu saja akan meningkat seiring waktu, dan pustaka regexp standar saat ini adalah pengganti untuk implementasi yang jauh lebih baik yang akan segera hadir. Jadi, kalah dari keduanya itu tidak mengejutkan, dan dalam waktu dekat margin harus lebih sempit.

Untuk benchmark k-nukleotida, agak sulit untuk membandingkan karena kode Java terlihat menggunakan algoritma yang berbeda. Kode Go pasti akan mendapat manfaat dari penyusun, penjadwal, dan peningkatan pengalokasi yang akan datang, bahkan seperti yang ditulis, tetapi seseorang harus menulis ulang kode Go untuk melakukan sesuatu yang lebih pintar jika kita ingin membandingkan lebih akurat.

Java menang dalam tolok ukur mandelbrot karena itu semua aritmatika dan loop floating point, dan ini adalah tempat yang bagus untuk JVM untuk menghasilkan kode mesin yang sangat baik dan mengerek hal-hal saat runtime. Go, sebagai perbandingan, memiliki kompiler yang cukup sederhana yang tidak mengangkat, membuka gulungan, atau menghasilkan kode mesin yang sangat ketat saat ini, jadi tidak mengherankan jika ia hilang. Namun, kita harus ingat bahwa pengaturan waktu Java tidak menghitung waktu mulai JVM atau berapa kali perlu dijalankan agar JVM dapat melakukan JIT dengan baik. Untuk program jangka panjang, ini tidak relevan, tetapi penting dalam beberapa kasus.

Sedangkan untuk sisa tolok ukur, Java dan Go pada dasarnya neck-in-neck, dengan Go mengambil secara signifikan lebih sedikit memori dan dalam kebanyakan kasus lebih sedikit kode. Jadi, sementara Go lebih lambat dari Jawa dalam beberapa tes tersebut, Java cukup cepat, Go melakukan perbandingan dengan cukup baik, dan Go mungkin akan menjadi lebih cepat dalam waktu dekat.

Saya menantikan ketika gccgo (kompiler Go yang menggunakan codegen gcc) sudah matang; yang seharusnya membuat Go cukup sejalan dengan C untuk banyak jenis kode, yang akan menarik.

Kyle C
sumber
2
Bagus sekali, untuk memahami bahwa selalu diperlukan untuk melihat kode sumber dan memeriksa apa yang sedang dilakukan!
igouy
1
Pada waktu start-up Java untuk program-program itu, lihat shootout.alioth.debian.org/help.php#java
igouy
2
Itu persis jenis jawaban yang saya harapkan, terima kasih!
Greg Slodkowicz
Penggunaan kode & memori yang jauh lebih sedikit, dikompilasi ke kode mesin, dirancang lebih baik. Semua ini mengambil alih kekurangan kecepatan.
Moshe Revah
22
  1. Tanpa mengatakan masalah mana yang diselesaikan, seluruh tolok ukur tidak ada gunanya.
  2. JVM dan CLR keduanya menggunakan JIT untuk menghasilkan kode mesin. Tidak ada alasan ini harus lebih lambat. Hanya perlu waktu lama untuk boot.
  3. Go dirancang untuk membangun dengan cepat . Anda tidak memiliki banyak waktu kompilasi dan optimisasi waktu boot. Go mengkompilasi pustaka standarnya sendiri saat aplikasi Java mem-boot.

Bisakah Go lebih cepat saat runtime? Iya nih. Akankah Go menjadi lebih cepat saat runtime? Saya tidak tahu Mungkin pembangun kompiler akan menambahkan optimasi opsional dengan biaya waktu kompilasi. Tapi saya pikir mereka tidak begitu tertarik. Mereka bekerja di Google.
Apa yang mereka inginkan adalah bahasa yang memungkinkan pengembangan cepat dan berkinerja baik pada apa yang mereka lakukan. Sial, bahkan jika tolok ukur itu kredibel, itu berarti mereka setengah lebih cepat dari C dan 14 kali lebih cepat dari Python. Ini lebih dari cukup.
Perangkat keras itu murah, kodenya mahal. Kode cenderung menjadi lebih besar dan lebih lambat saat Anda menginvestasikan uang, perangkat keras menjadi lebih murah dan lebih kecil. Anda ingin bahasa, yang tidak memerlukan 4 kerangka kerja dan 2000 kelas untuk mencapai sesuatu yang bermanfaat.
Tidak ada yang melekat dalam desain Go, yang membuatnya lambat. Namun ada sesuatu yang melekat pada desainer Go, yang membuatnya lebih lambat daripada perakitan: akal sehat.

back2dos
sumber
1
Kebanyakan (semua?) JIT dikompilasi selama runtime, bukan ketika kode pertama kali dimuat. Kode mesin ini mungkin tidak dihasilkan sama sekali untuk beberapa kode dan juga dapat dengan mudah dibatalkan, misalnya jika objsin for (obj : objs) { obj.meth() }memiliki implementasi yang berbeda methsetiap waktu dan JIT mencoba untuk mengikutinya. Tentu saja, semua ini sebenarnya bermanfaat dalam kasus-kasus umum, tetapi masih patut diperhatikan.
@delnan: V8 JIT kode apa pun sebelum menjalankannya. Juga, LLVM dibangun dengan mempertimbangkan JITting, oleh karena itu (dengan beberapa upaya tentu saja) Anda dapat melakukan optimasi tepat pada waktunya, yang sebaliknya akan terjadi pada waktu kompilasi. Namun, optimasi tertentu, seperti analisis pelarian hanya benar-benar berfungsi dengan JIT.
back2dos
3
>> Tanpa mengatakan masalah mana yang diselesaikan << Lihat dan Anda akan menemukan bahwa halaman-halaman web DO mengatakan masalah mana yang diselesaikan. Bahkan, Anda akan menemukan kode sumber program, membangun perintah, menjalankan perintah, versi implementasi bahasa, ya da ya da ya
igouy
10

Saya juga memperhatikan bahwa Go sangat lambat dalam benchmark regex-dna . Russ Cox menjelaskan mengapa Go tidak tampil di benchmark ini . Alasannya adalah bahwa paket regexp Go menggunakan algoritma pencocokan yang berbeda yang berkinerja buruk dalam tolok ukur khusus ini tetapi mungkin dengan besaran lebih cepat di tolok ukur lain. Juga Ruby, Python dan bahasa scripting lainnya menggunakan implementasi C dari algoritma pencocokan regexp lain .

Akhirnya, Permainan Tingkatan Bahasa Komputer terdiri dari tolok ukur mikro yang mungkin tidak secara akurat mencerminkan banyak karakteristik bahasa yang diukur dan bahkan memediasi tayangan yang salah. Makalah penelitian ini , baru-baru ini diterbitkan oleh Google memberikan gambaran yang lebih akurat tentang beberapa karakteristik bahasa Go, Scala, Java dan C ++ - khususnya bagian "V. Analisis Kinerja". Jadi pada akhirnya Go hampir haus akan memori seperti halnya Java (81% dari memori Java) dan mengkonsumsi bahkan 170% memori sebanyak Scala (tidak dapat menemukan di koran apakah konsumsi memori JVM dipertimbangkan).

Tapi sekali lagi, Go masih muda dan masih dalam pengembangan berat (perubahan API)! Banyak perbaikan segera hadir.

Alex
sumber
3
>> Makalah penelitian ini, baru-baru ini diterbitkan oleh Google << Ini bukan makalah penelitian, dan tidak diterbitkan oleh Google. Ini adalah laporan pengalaman oleh seorang karyawan Google yang disajikan di bengkel Scala "Scala Days 2011".
igouy
>> mungkin tidak secara akurat mencerminkan banyak karakteristik dari bahasa yang diukur dan bahkan memediasi tayangan yang salah << Itu juga berlaku untuk program "loop recognition", dan mungkin juga berlaku untuk setiap perbandingan kinerja antara berbagai bahasa pemrograman. Sebenarnya penulis memberi tahu Anda - "Kami tidak mengeksplorasi aspek multi-threading, atau mekanisme tipe tingkat yang lebih tinggi ... kami juga tidak melakukan perhitungan numerik berat ..."
igouy
@igouy Di sampul Anda dapat membaca "Google" dan semua yang relevan ditutupi dengan referensi yang sesuai. Jadi mengapa ini bukan "makalah penelitian, diterbitkan oleh Google" jika Google disebutkan dengan alamat kantor pusatnya? Makalah penelitian bukan domain hanya akademisi.
Alex
Di sampul Anda dapat membaca alamat surat di mana penulis dapat dihubungi, dan alamat email penulis. Periksa URL pdf yang Anda poskan. Catat domainnya - days2011.scala-lang.org - the Scala Days 2011 "Workshop Scala.
igouy
1

Go lebih cepat dari Python dan sedikit lebih lambat dari Java. Pengalaman kasar saya menemukan Go jauh lebih cepat (1-2 order magnitude) daripada Python, dan sekitar 10-20% lebih lambat dari Java. Namun, Go sedikit lebih cepat daripada Java jika digunakan dengan quad-core (x64). Pergi juga jauh lebih efisien dalam hal memori RAM.

Saya ingin menambahkan beberapa poin tentang potensi Go untuk kinerja vs Java dan Python. Go memungkinkan lebih banyak hal yang dilakukan C yang secara konstan memungkinkan C mengungguli sebagian besar bahasa lainnya. Kehilangan cache cukup penting untuk menghindari kode kinerja tinggi. Mengurangi kesalahan cache membutuhkan pengontrolan tata letak memori struktur data Anda. Go memungkinkan Anda untuk melakukan itu. Java tidak yang membuatnya lebih sulit untuk menghindari patah memori dan cache.

Saat ini Java biasanya berjalan lebih cepat daripada Go, karena pengumpul sampah Jawa jauh lebih canggih. Meskipun tidak ada alasan pengumpul sampah Go tidak bisa jauh lebih baik. Pembuatan kode juga kemungkinan jauh lebih baik untuk Java saat ini. Go memiliki banyak potensi untuk ditingkatkan misalnya dengan dukungan untuk instruksi vektor dll.

Jadi saya pikir itu benar-benar hanya soal waktu sebelum Go edge melewati Java. Meskipun suka dengan kode bahasa apa pun kemungkinan tidak akan lebih cepat secara otomatis dengan ditulis dalam Go. Anda harus memanfaatkan fasilitas yang diberikan bahasa kepada Anda. Saya katakan Go hanya memberi lebih banyak peluang untuk menyempurnakan kode Anda.

Bagaimanapun, itu hanya pengalaman satu pengembang.

Milo Banks
sumber
4
Ini adalah pertanyaan berusia 8 tahun dan daya komputasi murah telah membuatnya tidak relevan. Jawaban Anda juga didasarkan pada "perasaan Anda" dan bukan data yang sulit. Saya tidak bermaksud mengecilkan hati Anda, tapi ...
Kayaman