"Optimalisasi prematur adalah akar dari semua kejahatan" adalah sesuatu yang hampir semua dari kita telah dengar / baca. Apa yang saya ingin tahu seperti apa optimasi tidak prematur, yaitu pada setiap tahap pengembangan perangkat lunak (desain tingkat tinggi, desain detail, implementasi tingkat tinggi, implementasi rinci dll) sejauh mana optimasi dapat kita pertimbangkan tanpa menyeberang ke sisi gelap.
optimization
Gaurav
sumber
sumber
Jawaban:
Ketika Anda mendasarkannya dari pengalaman? Bukan jahat. "Setiap kali kita melakukan X, kita mengalami kinerja yang brutal. Mari kita rencanakan untuk mengoptimalkan atau menghindari X sepenuhnya saat ini."
Kapan itu relatif tidak menyakitkan? Bukan jahat. "Menerapkan ini sebagai Foo atau Bar akan mengambil banyak pekerjaan, tetapi secara teori, Bar harus jauh lebih efisien. Ayo Buang itu."
Ketika Anda menghindari algoritma jelek yang akan sangat skala? Bukan jahat. "Pimpinan teknologi kami mengatakan algoritma pemilihan jalur yang kami usulkan berjalan dalam waktu faktorial; Saya tidak yakin apa artinya itu, tetapi dia menyarankan agar kami melakukan seppuku bahkan untuk mempertimbangkannya. Mari kita pertimbangkan sesuatu yang lain."
Kejahatan datang dari menghabiskan banyak waktu dan masalah pemecahan energi yang Anda tidak tahu sebenarnya ada. Ketika masalah benar-benar ada, atau ketika masalah psudo hantu mungkin diselesaikan dengan murah, kejahatan menghilang.
Steve314 dan Matthieu M. meningkatkan poin dalam komentar yang seharusnya dipertimbangkan. Pada dasarnya, beberapa jenis optimisasi "tanpa rasa sakit" sama sekali tidak sepadan karena peningkatan kinerja sepele yang mereka tawarkan tidak sebanding dengan kebingungan kode, mereka menduplikasi peningkatan yang telah dilakukan oleh kompiler, atau keduanya. Lihat komentar untuk beberapa contoh bagus dari non-perbaikan yang terlalu pintar-setengahnya.
sumber
i
tidak ditandatangani,i / 2
dapat diganti olehi >> 1
. Lebih cepat. Tetapi juga lebih samar (tidak semua orang akan melihat efeknya, bahkan mereka yang kehilangan waktu). Tetapi yang terburuk adalah kompiler akan tetap melakukannya, jadi mengapa mengaburkan kode sumber;)?i/2
memang hot spot dan (tidak dapat dipercaya, tapi mari kita asumsikan)i>>1
membuatnya lebih cepat, maka lakukan, dan beri komentar bahwa profil ini menunjukkan bahwa ini lebih cepat. Jika ini memang diperlukan di mana saja (yang saya ragu, karena, seperti yang dikatakan Matthieu, kompiler harus cukup pintar untuk melakukan ini sendiri), pemula akan belajar sesuatu, jika tidak (yang kemungkinan), mengapa Anda ingin menghubungkan kepala mereka dengan cerita rakyat yang tidak dibutuhkan?Kode aplikasi seharusnya hanya sebagus yang diperlukan, tetapi kode perpustakaan harus sebaik mungkin, karena Anda tidak pernah tahu bagaimana perpustakaan Anda akan digunakan. Jadi ketika Anda menulis kode pustaka, itu harus bagus di semua aspek, baik itu kinerja, ketahanan, atau kategori lainnya.
Selain itu, Anda perlu memikirkan kinerja saat merancang aplikasi dan memilih algoritma . Jika tidak dirancang untuk menjadi performan, tidak ada tingkat peretasan yang dapat menjadikannya berkinerja setelahnya dan tidak ada optimasi mikro yang melebihi algoritma yang unggul.
sumber
Jenis yang datang sebagai hasil dari masalah yang diketahui.
sumber
Sulit mengatakan yang baik dan yang jahat. Siapa yang berhak? Jika kita melihat alam, tampaknya kita diprogram untuk bertahan hidup dengan definisi luas tentang "bertahan hidup" yang mencakup mewariskan gen kita kepada keturunan.
Jadi saya akan mengatakan, paling tidak sesuai dengan fungsi dasar dan pemrograman kami, optimasi itu tidak jahat ketika sejalan dengan tujuan reproduksi. Bagi para pria, ada yang berambut pirang, berambut cokelat, berambut merah, banyak yang cantik. Untuk cewek, ada cowok, dan beberapa dari mereka tampaknya baik-baik saja.
Mungkin kita harus mengoptimalkan ke arah tujuan itu, dan ada baiknya menggunakan profiler. Profiler akan membiarkan Anda memprioritaskan pengoptimalan dan waktu Anda lebih efektif selain memberi Anda informasi terperinci tentang hotspot dan mengapa hal itu terjadi. Ini akan memberi Anda lebih banyak waktu luang yang dihabiskan untuk reproduksi dan pengejarannya.
sumber
The kutipan penuh mendefinisikan ketika optimasi tidak prematur:
Anda dapat mengidentifikasi kode kritis dalam banyak cara: struktur data kritis atau algoritma (misalnya banyak digunakan atau "inti" proyek) dapat memberikan optimasi besar, banyak optimasi kecil diidentifikasi melalui profiler, dan sebagainya.
sumber
Anda harus selalu memilih solusi "cukup baik" dalam semua kasus berdasarkan pengalaman Anda.
Pepatah pengoptimalan mengacu pada penulisan "kode yang lebih kompleks daripada 'cukup baik' untuk membuatnya lebih cepat" sebelum benar-benar mengetahui bahwa itu perlu, karenanya membuat kode lebih kompleks daripada yang diperlukan. Kompleksitas adalah yang membuat segalanya sulit, jadi itu bukan hal yang baik.
Ini berarti bahwa Anda tidak boleh memilih "super kompleks" file 100 Gb dengan secara swap transparan ke disk "menyortir rutin ketika semacam sederhana akan dilakukan, tetapi Anda juga harus membuat pilihan yang baik untuk jenis sederhana di tempat pertama. Pilih Bubble Sort secara buta atau "pilih semua entri secara acak dan lihat apakah semuanya sesuai. Ulangi." Jarang baik.
sumber
Aturan umum saya: jika Anda tidak yakin Anda akan perlu optimasi, anggap Anda tidak. Tetapi perlu diingat ketika Anda perlu mengoptimalkan. Ada beberapa masalah yang bisa Anda ketahui di muka. Ini biasanya melibatkan pemilihan algoritma dan struktur data yang baik. Misalnya, jika Anda perlu memeriksa keanggotaan dalam koleksi, Anda dapat yakin bahwa Anda akan memerlukan beberapa jenis struktur data yang ditetapkan.
sumber
Dalam pengalaman saya, pada tahap implementasi terperinci jawabannya terletak pada profiling kode. Penting untuk mengetahui apa yang harus lebih cepat dan apa yang dapat diterima dengan cepat.
Penting juga untuk mengetahui di mana sebenarnya hambatan kinerja - mengoptimalkan bagian dari kode yang hanya membutuhkan 5% dari total waktu untuk menjalankan tidak akan ada gunanya.
Langkah 2 dan 3 menjelaskan optimasi non-prematur:
sumber
Ini bukan optimasi ketika memilih hal-hal yang sulit diubah misalnya: platform perangkat keras.
Memilih struktur data adalah contoh yang baik - penting untuk memenuhi persyaratan (kinerja) fungsional dan non-fungsional. Tidak mudah diubah dan itu akan mendorong semua hal lain di aplikasi Anda. Struktur data Anda mengubah algoritma apa yang tersedia dll.
sumber
Saya hanya tahu satu cara untuk menjawab pertanyaan ini, dan itu adalah untuk mendapatkan pengalaman dalam penyempurnaan kinerja. Itu berarti - menulis program, dan setelah ditulis, temukan speedup di dalamnya, dan lakukan iteratif. Ini salah satu contohnya.
Inilah kesalahan yang dibuat kebanyakan orang: Mereka mencoba mengoptimalkan program sebelum benar-benar menjalankannya. Jika mereka telah mengambil kursus pemrograman (dari seorang profesor yang tidak benar-benar memiliki banyak pengalaman praktis) mereka akan memiliki kacamata berwarna O-besar, dan mereka akan berpikir itu tentang semua itu . Ini semua masalah yang sama, optimasi sebelumnya. **
Seseorang berkata: Pertama, perbaiki, lalu perbaiki. Mereka benar.
Tetapi sekarang untuk si penendang: Jika Anda telah melakukan ini beberapa kali, Anda mengenali hal-hal konyol yang Anda lakukan sebelumnya yang menyebabkan masalah kecepatan, jadi Anda secara naluriah menghindarinya. (Hal-hal seperti membuat struktur kelas Anda terlalu berat, dibanjiri notifikasi, ukuran panggilan fungsi yang membingungkan dengan biaya waktunya, daftarnya terus-menerus ...) Anda secara naluriah menghindarinya, tetapi tebak seperti apa kelihatannya bagi yang kurang- berpengalaman: optimasi prematur!
Jadi debat konyol ini berlangsung terus-menerus :)
** Hal lain yang mereka katakan adalah Anda tidak perlu khawatir lagi, karena kompiler sangat bagus, dan mesin sangat cepat saat ini. (KIWI - Kill It With Iron.) Tidak ada peningkatan kecepatan perangkat keras atau sistem eksponensial (dilakukan oleh insinyur pekerja keras yang sangat pintar) yang mungkin dapat mengompensasi perlambatan perangkat lunak eksponensial (dilakukan oleh programmer yang berpikir seperti ini).
sumber
Ketika persyaratan atau pasar secara khusus memintanya.
Misalnya kinerja adalah persyaratan dalam sebagian besar aplikasi keuangan karena latensi rendah sangat penting. Bergantung pada sifat instrumen yang diperdagangkan, pengoptimalan dapat berubah dari menggunakan algoritme non-penguncian dalam bahasa tingkat tinggi hingga menggunakan bahasa tingkat rendah dan bahkan ekstrem - menerapkan algoritme pencocokan pesanan pada perangkat keras itu sendiri (menggunakan FPGA misalnya ).
Contoh lain adalah beberapa jenis perangkat yang disematkan. Ambil contoh rem ABS; pertama ada keamanan, ketika Anda menekan istirahat mobil harus melambat. Tetapi ada juga kinerja, Anda tidak ingin ada penundaan ketika Anda mencapai istirahat.
sumber
Kebanyakan orang akan menyebut optimasi prematur, jika Anda mengoptimalkan sesuatu yang tidak menghasilkan "kegagalan lunak" (itu berfungsi tetapi masih tidak berguna) dari sistem karena kinerja.
Contoh dunia nyata.
Jika sort bubble saya membutuhkan 20ms untuk berjalan, mengoptimalkannya ke quicksort 1ms tidak akan meningkatkan utilitas keseluruhan dengan cara yang berarti meskipun ada peningkatan kinerja 2000%.
Jika sebuah halaman web membutuhkan 20 detik untuk memuat dan kami menguranginya menjadi 1 detik, ini dapat meningkatkan utilitas situs web dari 0 hingga hampir tak terbatas. Pada dasarnya sesuatu yang rusak karena terlalu lambat, kini bermanfaat.
sumber
Apa jenis optimasi yang tidak prematur?
Optimasi yang memperbaiki masalah kinerja yang diketahui dengan aplikasi Anda, atau optimisasi yang memungkinkan aplikasi Anda memenuhi kriteria penerimaan yang ditentukan dengan baik.
Setelah diidentifikasi, beberapa waktu harus diambil untuk menetapkan perbaikan dan manfaat kinerja harus diukur.
(Yaitu bukan - "Saya pikir sedikit kode ini sepertinya bisa lambat, saya akan mengubah X untuk menggunakan Y sebagai gantinya dan itu akan lebih cepat").
Saya telah menemukan banyak "optimasi" prematur yang akhirnya membuat kode lebih lambat - dalam hal ini, saya menganggap prematur berarti 'tidak dipikirkan'. Kinerja harus diperbandingkan sebelum dan sesudah optimasi dan hanya kode yang benar-benar meningkatkan kinerja yang disimpan.
sumber
Benar. Sayangnya itu juga salah satu kutipan pemrograman yang paling banyak disalahgunakan sepanjang masa. Karena Donald Knuth menciptakan meme, ada baiknya menambahkan beberapa konteks asli dari kutipan:
Perhatikan bahwa Knuth berbicara secara khusus tentang kecepatan eksekusi di runtime .
Juga, ia menulis artikel pada 1974 ketika sumber daya mesin mana pun yang memiliki korelasi premium dan negatif antara kecepatan eksekusi dan rawatan program (kecepatan lebih tinggi - kurang dapat dirawat) mungkin lebih kuat dari sekarang.
OK, untuk menjawab pertanyaan Anda, menurut Donald Knuth, optimisasi BUKAN prematur jika itu memperbaiki hambatan kinerja serius yang telah diidentifikasi (diukur secara ideal dan ditunjukkan dengan tepat selama pembuatan profil).
Seperti yang saya katakan sebelumnya, "optimasi prematur" adalah salah satu meme yang paling banyak disalahgunakan, jadi jawabannya tidak akan lengkap tanpa beberapa contoh hal-hal yang bukan optimasi prematur tetapi terkadang diabaikan seperti itu:
Lebih jauh bahkan tidak terkait dengan kecepatan eksekusi runtime:
desain muka bijaksana
pengetikan statis (!)
dll / segala bentuk upaya mental
sumber