Selama kontes Google Code Jam saat ini (2013) , ada masalah yang membawa 200+ baris kode orang C ++ dan Java dibandingkan dengan orang Python yang menyelesaikan masalah yang sama hanya menggunakan 40 baris kode.
Python tidak secara langsung dapat dibandingkan dengan C ++ dan Java tetapi perbedaan dalam verbositas saya pikir mungkin memiliki pengaruh pada efisiensi algoritma.
Seberapa pentingkah mengetahui algoritma yang tepat dibandingkan dengan pilihan bahasa? Bisakah program Python yang diimplementasikan dengan sangat baik diimplementasikan dalam C ++ atau Java dengan cara yang lebih baik (menggunakan algoritma yang sama) dan apakah ini ada kaitannya dengan verbositas alami dari bahasa pemrograman tertentu?
java
c++
algorithms
python
superspacemarines
sumber
sumber
Jawaban:
Jelas, jika Anda mempertimbangkan pertanyaan ini dalam konteks sesuatu seperti Google Code Jam, maka pemikiran algoritmik jelas lebih penting ketika harus menyelesaikan masalah algoritmik.
Dalam kehidupan sehari-hari, bagaimanapun, sekitar satu juta faktor lain harus dipertimbangkan juga, yang membuat pertanyaannya jauh lebih sedikit hitam vs putih.
Hanya contoh tandingan: Jika Anda membutuhkan 200 saluran lagi di Jawa, tetapi semua orang di perusahaan Anda mengenal Jawa, ini bukan masalah besar. Jika Anda bisa menulisnya dalam 5 baris Python atau bahasa lain, tetapi Anda akan menjadi satu-satunya di perusahaan yang mengetahui bahasa itu - itu adalah masalah besar. Sebenarnya masalah besar, bahwa Anda bahkan tidak akan diizinkan untuk melakukannya dan malah harus menulisnya di Jawa.
Dari perspektif pengrajin, kami selalu mencoba untuk mendekati dengan alat yang tepat untuk pekerjaan itu, tapi kata yang tepat dalam ada begitu rumit yang satu dapat dengan mudah mendapatkan salah.
Sebaliknya, saya menemukan pemikiran algoritmik di perusahaan hampir tidak ada. Hanya beberapa orang terpilih yang memilikinya, sedangkan rata-rata joe sering sudah kesulitan memperkirakan kerumitan runtime loop, pencarian, dll.
Namun, dalam hal kompetisi algoritmik, pengalaman pribadi saya dari berkompetisi di dalamnya selama beberapa tahun, dengan jelas memberi tahu saya bahwa Anda harus berpegang pada satu bahasa. Kecepatan adalah faktor utama dan Anda tidak bisa membuang waktu untuk alat Anda, ketika Anda harus mendedikasikannya untuk menyelesaikan masalah dalam batas waktu. Juga pertimbangkan bahwa menulis 200 baris kode Java tanpa berpikir masih jauh lebih cepat daripada kerajinan tangan 50 baris kode python rumit yang membutuhkan banyak pemikiran, namun keduanya memecahkan kurang lebih masalah yang sama.
Oh dan akhirnya, pastikan Anda memahami perbedaan utama antara kode kompetisi algoritmik dan kode produksi perusahaan. Saya telah melihat coders algoritmik yang fantastis, yang menulis kode mengerikan yang tidak akan pernah saya terima dalam suatu produk.
sumber
Saya berpendapat bahwa, bahkan di luar kompetisi, pemikiran algoritmik lebih penting daripada mengetahui setiap trik untuk bahasa tertentu.
Tentu saja, Anda ingin mengetahui bahasa tempat Anda bekerja sebaik mungkin, tetapi bahasa datang dan pergi, sementara kemampuan untuk berpikir secara abstrak dalam hal algoritme adalah keterampilan yang sangat dapat ditransfer.
Contoh kasus: jika saya ingat dengan benar, ada posting di sini tentang Programmer beberapa waktu lalu di mana seseorang mengeluh tentang kegagalan FizzBuzz dalam sebuah wawancara dan menyalahkan kurangnya pengetahuan tentang operator modulo Java untuk itu. Kesimpulan ini salah - kurangnya pengetahuan tentang cara kerja modulo membuatnya tidak dapat berpikir secara algoritmik tentang masalah dan menyelesaikannya, bahkan tanpa adanya operator modulo yang berdedikasi. Lebih jauh: Java memiliki kelas Tree - bagaimana jika, di masa depan, Anda harus bekerja dengan bahasa yang tidak mengimplementasikan kelas ini? Sekali lagi, kemampuan untuk memikirkan masalah mengalahkan detail spesifik bahasa.
Saya akui bahwa contohnya sederhana, tetapi membantu menjelaskan maksudnya.
sumber
Masalah bahasa.
DARPA dan Angkatan Laut AS melakukan percobaan baku tembak hampir 20 tahun yang lalu. Pemenang pelarian kuda hitam adalah Haskell. Ada dan C ++ keduanya diwakili; Java tidak.
Sekitar waktu yang sama, Pratt & Whitney melakukan studi penambangan data pada proyek-proyek pengendali mesin jet, melihat timecard dan data pelacak bug. Mereka menemukan bahwa Ada memberi dua kali lipat produktivitas programmer dan 1/4 kepadatan cacat dari bahasa lain yang mereka gunakan.
Atari biasa menggunakan FORTH untuk mengembangkan videogame, dan fakta bahwa mereka menggunakan FORTH dianggap sangat eksklusif.
Komentar Paul Graham tentang penggunaan LISP sudah dikenal luas. Erann Gat ini komentar tentang LISP di JPL sama-sama meyakinkan, meskipun tidak terkenal.
Perangkat lunak avionik Boeing 777 hampir semuanya Ada. Pengalaman mereka sangat bagus, meskipun satu subkontraktor utama harus memulai dari awal.
Masalah bahasa.
sumber
Beberapa poin:
Posisi teratas cenderung C ++ / C / Java, terlepas dari berapa banyak baris kode perbedaannya antara itu dan beberapa bahasa lainnya. Ini mungkin lebih tentang bahwa coders top cenderung memilih bahasa-bahasa ini dari yang lain, mungkin karena kecepatan mentah mereka.
Sayangnya Anda tidak dapat dengan mudah melihat bahasa pemrograman di Google Code Jam, tetapi saya mengunduh beberapa yang top dan, sejauh yang saya ingat, ini sebagian besar C / C ++. TopCoder (situs hosting kontes pemrograman online yang populer) sebagian besar memiliki hasil yang serupa.
Karena levelnya cukup rendah, saya yakin Anda tidak akan dengan mudah mengalahkan C / C ++ dalam hal waktu berjalan mentah (dan Java tidak jejak terlalu jauh di belakang). Dari pengalaman saya, bahasa yang diketik secara dinamis cenderung jauh lebih lambat daripada bahasa yang diketik secara statis. Solusi optimal mungkin bahkan tidak cukup cepat dalam beberapa bahasa, tetapi ini seharusnya tidak menjadi aturan umum.
Algoritma yang tepat sangat penting. Jika Anda tahu cara menyelesaikan semua masalah (dalam perincian tinggi) sejak awal, dan Anda adalah pembuat kode yang baik dan cepat, Anda kemungkinan besar akan menang, terlepas dari bahasa mana Anda memasukkan kode (dengan asumsi solusi optimal dalam bahasa itu) cukup cepat).
Jumlah garis yang lurus bukanlah masalah besar. Setelah Anda mendapatkan pengalaman pemrograman yang cukup, Anda akan tahu bahwa Anda dapat menghabiskan 10 menit memprogram 10 baris atau 200 baris, semuanya tergantung seberapa rumitnya garis tersebut. Juga, jika Anda telah membuat kode kode yang sama ratusan kali, Anda akan dapat melakukannya dengan sangat cepat. Tidak terlalu menyebutkan semua makro yang sering digunakan para pengkode C / C ++ teratas untuk mengoptimalkan waktu pengkodean mereka.
Frank membuat poin yang bagus - (di luar kompetisi pemrograman) Anda tidak dapat melakukan pengkodean dengan Python untuk perusahaan Anda jika seluruh basis kode mereka ada dalam C atau apa pun, Anda harus menyesuaikan diri dengan bahasa mereka.
Cukup mudah untuk beralih antar bahasa, tidak mudah untuk membangun pengetahuan berpikir algoritmik bertahun-tahun. Saya berani bertaruh hampir semua programmer hebat dapat beralih ke bahasa lain (agak mirip) dalam, katakanlah, seminggu. Mungkin dia tidak akan cukup baik untuk memenangkan kompetisi pemrograman dalam bahasa itu (berikan 2 minggu lagi), tetapi akan memiliki dasar-dasarnya.
sumber
Bisakah logika yang sama diimplementasikan lebih baik di C ++? Tentu saja bisa, jika lebih baik maksud Anda lebih cepat dan lebih hemat memori. Masalahnya adalah bahwa jumlah upaya yang diperlukan untuk melakukannya secara signifikan lebih tinggi. Selain itu, secara teoritis Anda masih bisa naik ke level yang lebih rendah dan mengimplementasikannya dalam C murni atau bahkan ASM, yang akan memakan waktu lebih lama, tetapi Anda bisa memiliki kode yang lebih optimal.
Tentu saja, dalam hal kompetisi seperti Code Jam atau TopCoder itu bukan masalah besar, karena hanya 40 baris vs 200 baris. Di sisi lain dalam kompetisi jenis ini yang paling penting adalah kompleksitas waktu / ruang dari algoritma. Sementara dalam aplikasi kehidupan nyata, YMMV, dalam jenis kompetisi ini algoritma O (n) yang ditulis dalam bahasa paling lambat akan selalu mengalahkan O (n²) yang ditulis dalam bahasa tercepat. Terutama bahwa akan ada beberapa tes yang merupakan skenario terburuk.
Tapi selain kompetisi, jika kita berbicara proyek besar kehidupan nyata, maka itu tidak lagi 40 baris vs 200 baris. Dalam proyek-proyek besar itu basis kode besar mulai menjadi masalah. Di titik mana Anda dapat:
C ++ vs Python?
Python murni lambat. Itu sebabnya interpreter Python standar (CPython) ditulis dalam C. Praktis semua dengan fungsi built-in ditulis sebagai sangat dioptimalkan C. Python juga dapat dengan mudah digunakan bersama dengan pustaka C (melalui ctypes bawaan atau sebagai modul cpython asli ) dan dengan pustaka C ++ via Boost :: Python . Dengan cara ini Anda dapat menulis logika tingkat tinggi dengan Python, bahasa yang fleksibel, memungkinkan pembuatan prototipe dan adaptasi cepat (artinya Anda dapat menghabiskan lebih banyak waktu mengutak-atik dan meningkatkan algoritme Anda). OTOH, Anda dapat menulis fungsi pustaka tingkat bawah di modul C atau C ++. Contoh bagus dari pendekatan semacam itu adalah SciPy, yang merupakan pustaka Python, namun di bawah kap ia menggunakan pustaka numerik yang sangat dioptimalkan seperti ATLAS, LAPACK, Intels MKL atau ACML AMD.
sumber
Menurut pendapat saya apa yang oleh orang banyak dianggap sebagai "bahasa pemrograman" sebenarnya adalah tiga hal terpisah:
Misalnya ketika seseorang mengemukakan C # dalam diskusi Anda mungkin berpikir dia berbicara tentang sintaksis bahasa (1) tetapi 95% yakin bahwa diskusi tersebut akan melibatkan .Net framework (3). Jika Anda tidak merancang bahasa baru, sulit dan biasanya tidak ada gunanya mengisolasi (1) dan mengabaikan (2) dan (3). Itu karena IDE dan perpustakaan standar adalah "faktor kenyamanan", hal-hal yang secara langsung memengaruhi pengalaman menggunakan alat tertentu.
Beberapa tahun terakhir saya juga berpartisipasi dalam Google Code Jam. Pertama kali saya memilih C ++ karena memiliki dukungan yang bagus untuk membaca input. Misalnya membaca tiga bilangan bulat dari input standar di C ++ terlihat seperti ini:
Sedangkan di C # yang sama akan terlihat seperti ini:
Itu lebih banyak overhead mental untuk fungsi sederhana. Hal-hal menjadi lebih rumit di C # dengan input multiline. Mungkin saya belum menemukan cara yang lebih baik saat itu. Ngomong-ngomong, saya gagal melewati babak pertama karena saya punya bug yang tidak bisa saya perbaiki sebelum akhir putaran. Ironisnya metode pembacaan input mengaburkan bug. Masalahnya sederhana, input berisi angka yang terlalu besar untuk integer 32 bit. Dalam C #
int.Parse(string)
akan melempar pengecualian tetapi dalam C ++ aliran input file akan menetapkan bendera kesalahan tertentu dan gagal diam-diam membuat pengembang tidak curiga tidak menyadari masalah.Kedua contoh menunjukkan bagaimana perpustakaan digunakan daripada sintaksis bahasa. Yang pertama menunjukkan verbositas dan yang lain menunjukkan reliabilitas. Banyak perpustakaan yang porting ke beberapa bahasa dan beberapa bahasa dapat menggunakan perpustakaan yang tidak secara khusus dibangun untuk mereka (lihat jawaban @ vartec tentang Python dengan perpustakaan C).
Untuk menyelesaikannya, mengetahui algoritma yang tepat membantu. Dalam kompetisi coding, sangat penting, terutama ketika sumber daya seperti waktu eksekusi dan memori sengaja dibatasi. Dalam pengembangan aplikasi ini disambut baik tetapi umumnya tidak penting. Pemeliharaan lebih penting di sana. Hal ini dapat dicapai dengan menerapkan pola desain yang benar, memiliki arsitektur yang baik, kode yang dapat dibaca dan dokumentasi yang relevan dan semua metode tersebut sangat bergantung pada perpustakaan internal dan pihak ketiga. Jadi, saya merasa lebih penting untuk mengetahui jenis roda apa yang sudah ditemukan dan bagaimana mereka cocok kemudian bagaimana membuat roda saya sendiri.
sumber
Main
dan beberapa hal di dalamMain
metode (contoh kelas input saya dan aliran output dan lingkaran kasus).Jika Anda ingin bersaing dalam kompetisi pemrograman berjangka waktu, Anda harus mempelajari bahasa yang paling ekspresif yang diperbolehkan dalam kompetisi. Perl mungkin yang terbaik, diikuti oleh Ruby atau Python. Anda masih memerlukan fasilitas yang baik dengan algoritma, tetapi setidaknya Anda tidak akan terjebak menulis sesuatu seperti
dari pada
Jangan khawatir tentang belajar beberapa perpustakaan. Semuanya sangat mirip dan dokumentasinya online. Menjadi fasih dalam bahasa yang lebih ekspresif akan membuat Anda menjadi programmer yang lebih baik (tetapi mungkin frustrasi) dalam bahasa yang kurang ekspresif. Yang sebaliknya tidak benar.
NB
Perbedaan antara 200 baris kode dan 40 baris kode sangat besar, dan bahkan lebih besar ketika perbedaan antara program baris 200.000 dan program baris 40.000. Maka perbedaan antara tim lima ditambah manajer, dan tim satu atau dua.
sumber
Algoritma apa pun dapat diimplementasikan dalam bahasa pemrograman apa pun. Setelah semua, itu bukan sintaks yang penting. Tetapi menggunakan bahasa tingkat tinggi seperti Python memang memiliki kelebihan tersendiri. Lebih sedikit pekerjaan dan lebih sedikit jumlah pengkodean. Jadi untuk mengimplementasikan suatu algoritma dalam Python, Anda akan membutuhkan lebih sedikit baris daripada apa yang diperlukan dalam bahasa tingkat rendah seperti C.
Python memiliki sebagian besar struktur data yang dibangun ke perpustakaannya. Tetapi dalam C, kita harus mulai dari awal dan menggunakan struktur untuk membangun semuanya. Tentu saja ada perbedaan antara bahasa tingkat tinggi dan tingkat rendah, tetapi bahasa tersebut seharusnya tidak menghentikan Anda dari penerapan algoritma apa pun.
sumber
Sementara meramalkan contoh "40 LoC vs 200 LoC", mengatakan, "hanya seperlima dari total LoC yang jelas lebih cepat untuk ditulis jadi pasti lebih baik" mungkin tampak menggoda, saya benar-benar berpikir ada sedikit kebenaran yang bisa ditemukan di sana.
Mengoptimalkan untuk LoC paling sedikit hampir tidak pernah merupakan ide yang baik menurut saya. Ya, setiap LoC yang ditulis berpotensi menimbulkan bug, dan Anda tidak perlu men-debug apa yang tidak pernah Anda tulis, dll. Intinya, optimalkan keterbacaan dan decoupledness. Tidak masalah jika Anda memecahkan masalah menggunakan regex besar 20 baris, yang bertentangan dengan menulis modul 1k LoC. Regex akan menjadi dinding buram, sangat rentan terhadap bug, sulit dipahami, mimpi buruk untuk berubah tanpa mengubah perilaku itu dengan cara yang tidak dapat diakses dll.
Menyingkirkan platplate dan verbositas yang tidak menambah nilai sama sekali dan bagus, tetapi di sisi lain, menggunakan sesuatu seperti Java atau C #, memiliki pengetahuan tentang pola desain dan alat-alat seperti resharper memungkinkan Anda begitu banyak fleksibilitas dalam refactoring kode , membersihkannya dari waktu ke waktu, memecah barang-barang, dll., yang akan jauh lebih sulit jika Anda menuliskannya sebagai skrip python atau aplikasi ruby yang jauh lebih kecil.
Perbandingan yang sangat jitu: Saya lebih suka memiliki 100k LoC dari kode C # yang dipisahkan oleh tes tertutup, diisi dengan hal-hal "berlebihan" seperti pola strategi, pabrik dll, daripada aplikasi python 20k yang hanya "menyelesaikan pekerjaan". 5 kali lebih banyak kode atau tidak, arsitektur menang setiap hari.
Saya sepenuhnya setuju beberapa jenis pekerjaan lebih mudah dan lebih nyaman dalam beberapa bahasa, tetapi saya lebih percaya dalam memilih bahasa Anda berdasarkan alat apa yang Anda butuhkan dan apa persyaratannya (dan mungkin dalam waktu dekat).
sumber