Saya telah menjumpai banyak orang yang secara dogmatis menentang apa pun yang dapat dianggap "optimisasi" dalam arti kata umum dalam bahasa Inggris, dan mereka sering mengutip kata demi kata (sebagian) kutipan "optimasi prematur adalah akar dari semua kejahatan" sebagai pembenaran untuk sikap mereka, menyiratkan bahwa mereka menafsirkan apa pun yang saya bicarakan adalah "optimasi prematur". Namun, pandangan ini kadang-kadang sangat mengakar sehingga mereka mengabaikan hampir semua jenis penyimpangan algoritmik atau struktur data dari implementasi "naif" yang paling murni ... atau setidaknya penyimpangan dari cara mereka melakukan sesuatu sebelumnya.Bagaimana seseorang dapat mendekati orang-orang seperti ini dengan cara membuat mereka "membuka telinga lagi" setelah mereka berhenti dari mendengar tentang "kinerja" atau "optimasi"? Bagaimana saya membahas topik desain / implementasi yang berdampak pada kinerja tanpa membuat orang langsung berpikir: "Orang ini ingin menghabiskan dua minggu pada sepuluh baris kode?"
Sekarang, sikap apakah "semua optimasi adalah prematur dan oleh karena itu jahat" atau tidak telah dibahas di sini serta di sudut-sudut lain dari Web , dan telah dibahas bagaimana mengenali kapan optimasi itu prematur dan karena itu jahat , tetapi sayangnya masih ada orang-orang di dunia nyata yang tidak cukup terbuka untuk tantangan iman mereka dalam Anti-Optimasi.
Upaya sebelumnya
Beberapa kali, saya telah mencoba memberikan penawaran lengkap dari Donald Knuth untuk menjelaskan bahwa "optimasi prematur buruk" ↛ "semua optimasi buruk":
Kita harus melupakan efisiensi kecil, katakanlah sekitar 97% dari waktu: optimasi prematur adalah akar dari semua kejahatan. Namun kita tidak boleh melewatkan peluang kita dalam 3% kritis itu.
Namun, ketika memasok seluruh kutipan, orang-orang ini kadang-kadang menjadi lebih yakin bahwa yang saya lakukan adalah Premature Optimization ™ dan menggali dan menolak untuk mendengarkan. Ini hampir seolah-olah kata "optimasi" membuat mereka takut: Pada beberapa kesempatan, saya dapat mengusulkan perubahan kode peningkatan kinerja yang sebenarnya tanpa mereka diveto dengan hanya menghindari penggunaan kata "optimiz (e | asi)" ( dan "kinerja" juga - kata itu menakutkan juga) dan alih-alih menggunakan beberapa ungkapan seperti "arsitektur alternatif" atau "implementasi yang ditingkatkan". Untuk alasan ini, sepertinya ini benar-benar dogmatisme dan bukan mereka yang sebenarnya mengevaluasi apa yang saya katakan secara kritis dan kemudian menolaknya sebagai tidak perlu dan / atau terlalu mahal.
sumber
Jawaban:
Tampaknya Anda mencari jalan pintas untuk tidak mencoba "implementasi naive paling murni" terlebih dahulu, dan langsung mengimplementasikan "solusi yang lebih canggih karena Anda tahu sebelumnya bahwa implementasi naif tidak akan melakukannya". Sayangnya, ini jarang akan berhasil - ketika Anda tidak memiliki fakta keras atau argumen teknis untuk membuktikan bahwa implementasi naif adalah atau akan terlalu lambat, Anda kemungkinan besar salah, dan apa yang Anda lakukan adalah optimasi prematur. Dan mencoba berdebat dengan Knuth adalah kebalikan dari memiliki fakta yang sulit.
Dalam pengalaman saya, Anda harus menggigit peluru dan mencoba "implementasi naif" terlebih dahulu (dan mungkin akan heran betapa seringnya ini cukup cepat), atau Anda setidaknya akan membuat perkiraan kasar tentang waktu berjalan, seperti:
"Implementasi naif akan menjadi O (n³), dan n lebih besar dari 100.000; itu akan berjalan beberapa hari, sedangkan implementasi tidak-begitu-naif akan berjalan di O (n), yang hanya akan memakan waktu beberapa menit" .
Hanya dengan argumen seperti itu, Anda dapat yakin bahwa optimasi Anda tidak prematur.
Hanya ada satu pengecualian dari IMHO : ketika solusi yang lebih cepat juga lebih sederhana dan lebih bersih, maka Anda harus menggunakan solusi yang lebih cepat sejak awal. Contoh standar adalah yang menggunakan kamus alih-alih daftar untuk menghindari kode loop yang tidak perlu untuk pencarian, atau penggunaan kueri SQL yang baik yang memberi Anda persis satu catatan hasil yang Anda butuhkan, bukan hasil besar yang harus difilter kemudian dalam kode. Jika Anda memiliki kasus seperti itu, jangan berdebat tentang kinerja- kinerja mungkin merupakan manfaat tambahan, tetapi kemungkinan besar tidak relevan, dan ketika Anda menyebutkannya, orang mungkin tergoda untuk menggunakan Knuth melawan Anda. Berdebat tentang keterbacaan, kode pendek, kode bersih, pemeliharaan - tidak perlu "menutupi" apa pun di sini, tetapi karena itu (dan hanya itu) adalah argumen yang benar di sini.
Menurut pengalaman saya, kasus terakhir jarang terjadi - kasus yang lebih umum adalah kita dapat menerapkan solusi sederhana dan naif yang lebih mudah dimengerti dan lebih sedikit kesalahan daripada yang lebih rumit, tetapi mungkin lebih cepat.
Dan tentu saja, Anda harus mengetahui persyaratan dan use case dengan cukup baik untuk mengetahui kinerja apa yang dapat diterima, dan ketika segala sesuatunya menjadi "terlalu lambat" di mata pengguna Anda. Di dunia yang ideal, Anda akan mendapatkan spesifikasi kinerja formal oleh pelanggan Anda, tetapi dalam proyek dunia nyata, kinerja yang diperlukan seringkali merupakan area abu-abu, sesuatu yang hanya akan diberitahukan oleh pengguna Anda ketika mereka mencatat bahwa program tersebut berperilaku "terlalu lambat" dalam produksi. Dan seringkali, itulah satu-satunya cara bekerja untuk mencari tahu ketika ada sesuatu yang terlalu lambat - umpan balik pengguna, dan kemudian Anda tidak perlu mengutip Knuth untuk meyakinkan rekan tim Anda bahwa "implementasi naif" mereka tidak memadai.
sumber
Tanyakan pada diri sendiri ini:
Ini adalah alasan untuk mengoptimalkan. Jadi, jika orang-orang menentang, cukup tunjukkan spesifikasi dan kembali ke mereka dan jelaskan kami perlu mengoptimalkan karena kami tidak memenuhi spesifikasi. Selain itu, orang akan kesulitan meyakinkan orang lain bahwa optimasi diperlukan.
Saya pikir poin utama dari kutipan ini adalah, jika Anda tidak memiliki masalah, jangan lakukan optimasi yang tidak perlu karena waktu dan energi dapat dihabiskan di tempat lain. Dari calon bisnis, ini masuk akal.
Sekunder, bagi mereka yang takut optimasi, selalu mendukung temuan kinerja dengan metrik. Seberapa cepat kodenya? Seberapa banyak peningkatan kinerja dari sebelumnya? Jika seseorang menghabiskan dua minggu hanya untuk meningkatkan kode 2% dari versi sebelumnya, jika saya bos Anda, saya tidak akan senang. Dua minggu itu bisa digunakan untuk mengimplementasikan fitur baru yang dapat menarik lebih banyak pelanggan dan menghasilkan lebih banyak uang.
Akhirnya, sebagian besar perangkat lunak tidak harus sangat dioptimalkan. Hanya dalam beberapa industri khusus kecepatan sangat penting. Jadi, sebagian besar waktu seseorang dapat menggunakan perpustakaan dan kerangka kerja yang sudah ada untuk efek yang baik.
sumber
Mulailah dengan prinsip bersama yang dibangun di atas arahan strategis grup Anda.
Prinsip Saya:
Prinsip pribadi saya dalam menulis kode adalah pertama-tama bertujuan untuk kebenaran dalam program saya, kemudian untuk profil itu dan menentukan apakah perlu optimasi. Saya profil kode saya sendiri karena programmer lain adalah konsumen potensial kode saya - dan mereka tidak akan menggunakannya jika lambat - dengan demikian untuk kode saya, kecepatan adalah fitur.
Jika konsumen Anda adalah pelanggan, pelanggan Anda akan memberi tahu Anda jika Anda membutuhkan kode yang lebih cepat.
Namun, ada pilihan kode yang terbukti dan lebih baik yang bisa dibuat. Saya lebih suka memperbaikinya dalam draf pertama saya karena beberapa alasan:
Dengan asumsi kebutuhan untuk optimasi sudah benar
Dengan asumsi ini adalah bagian yang sangat penting dari kode Anda yang perlu dioptimalkan, Anda dapat memberi tahu perumpamaan tentang Schlemiel the Painter , atau menekankan sisa dari kutipan tersebut:
Timbang biaya kompleksitas tambahan
Terkadang ada biaya nyata dalam hal pemeliharaan kompleksitas yang ditambahkan. Dalam hal ini, Anda mungkin menyimpan implementasi sekunder dalam fungsi atau subkelas yang berbeda, dan menerapkan unittests yang sama untuk itu sehingga tidak ada pertanyaan bahwa itu benar. Kemudian, jika Anda membuat profil kode Anda dan menemukan implementasi yang naif sebagai hambatan, Anda dapat mengganti kode yang dioptimalkan dan secara nyata meningkatkan program Anda.
Kepemimpinan
Kadang-kadang masalahnya adalah ego - beberapa orang lebih suka menggunakan kode suboptimal atau buggy daripada meminta orang lain lebih benar daripada mereka. Anda mungkin ingin menghindari bekerja dengan orang-orang ini.
Kepemimpinan, terutama ketika Anda tidak memiliki otoritas posisi atas orang, adalah tentang membuat saran yang masuk akal dan membimbing orang lain ke konsensus. Jika Anda tidak dapat memandu tim Anda ke rapat pikiran, mungkin masalahnya tidak layak ditekan. Mungkin ada ikan yang lebih besar untuk digoreng.
sumber
Jalan ke depan adalah melupakan kutipan yang sebenarnya dan berbagai interpretasi - itu dogmatisme, baik cara untuk memfokuskan begitu banyak pada kutipan spesifik oleh seorang guru. Siapa bilang Knuth selalu benar?
Alih-alih fokus pada proyek di tangan, perangkat lunak yang Anda kembangkan bersama dengan rekan kerja yang tidak Anda setujui. Apa persyaratan untuk kinerja yang dapat diterima untuk perangkat lunak ini? Apakah lebih lambat dari ini? Kemudian optimalkan.
Anda tidak harus menyebutnya "optimisasi", Anda dapat menyebutnya "memperbaiki bug", karena ini merupakan definisi bug jika implementasi gagal memenuhi persyaratan.
Secara umum, ada dua kemungkinan mengenai pengoptimalan:
Kode yang dioptimalkan juga lebih pendek, lebih mudah dipahami dan lebih mudah dipelihara.
Kode yang dioptimalkan lebih kompleks untuk dipahami, membutuhkan waktu lebih lama untuk menulis dan menguji, atau akan lebih kompleks untuk berubah di masa depan jika persyaratan berubah dengan cara yang tidak terduga.
Jika kasusnya adalah (1) Anda bahkan tidak perlu berdebat tentang pengoptimalan. Tetapi jika (2) masalahnya, maka Anda terlibat dalam keputusan trade-off . Ini sebenarnya keputusan tingkat bisnis, bukan murni keputusan teknis. Anda harus mempertimbangkan biaya optimasi dengan manfaatnya. Agar ada manfaat, inefisiensi harus menjadi masalah sejak awal, baik karena pengalaman pengguna yang buruk atau peningkatan biaya perangkat keras atau sumber daya lainnya secara signifikan.
sumber
Saya pikir kutipan lengkap dalam konteks bersifat instruktif. Saya akan menyalin dari posting yang saya buat di Reddit dengan topik:
- Donald Knuth, Pemrograman Terstruktur dengan pergi ke Pernyataan , ACM Computing Survey, Vol 6, No. 4, Desember 1974, hal.268
Intinya, dan implikasinya, adalah bahwa ada hal-hal yang lebih penting untuk dikhawatirkan daripada menaruh perhatian Anda pada optimasi terlalu dini. Tentu saja, Anda harus hati-hati mempertimbangkan struktur data dan algoritma Anda (ini ada di 3%) tetapi Anda tidak perlu khawatir tentang apakah pengurangan lebih cepat daripada modulo (ini berada di 97%) sampai menjadi jelas bahwa optimasi tingkat rendah adalah perlu.
Yang pertama tidak selalu merupakan optimasi dalam arti yang dipikirkan rekan-rekan Anda, tetapi ini adalah optimasi dalam arti bahwa algoritma dan struktur data yang dipilih dengan buruk tidak optimal.
sumber
Dalam pengalaman saya, jika Anda mendapatkan penentangan seperti ini terhadap pengoptimalan secara teratur , orang tidak benar-benar mengeluh tentang pengoptimalan. Mereka mengeluh tentang apa yang Anda korbankan atas nama optimisasi. Ini biasanya keterbacaan, pemeliharaan, atau ketepatan waktu. Jika kode Anda dikirimkan dalam jumlah waktu yang sama, dan mudah dipahami, orang tidak akan peduli jika Anda menggunakan struktur data dan algoritma yang lebih efisien. Saran saya dalam hal ini adalah bekerja untuk membuat kode Anda lebih elegan dan dapat dikelola.
Jika Anda mendapatkan oposisi semacam ini sehubungan dengan kode orang lain, biasanya karena Anda menyarankan sejumlah besar pengerjaan ulang. Dalam kasus tersebut, Anda benar-benar memerlukan beberapa pengukuran aktual untuk menunjukkan upaya yang sepadan, atau mungkin mencoba untuk terlibat lebih awal dalam fase desain, sebelum kode ditulis. Dengan kata lain, Anda perlu membuktikannya dalam 3%. Jika kita menulis ulang semua kode yang tidak sesuai dengan keinginan kita, kita tidak akan pernah mencapai apa pun.
sumber
Deque
dari perpustakaan standar Java untuk mengganti sejumlah besar logika yang dibangun di sekitar yangArrayList
digunakan sebagai tumpukan saat bekerja pada kode ... dan ini ditandai untuk ubah ulasan. Dengan kata lain, pengulas ingin memiliki lebih banyak kode yang juga lebih lambat dan lebih rentan terhadap bug karena dia tidak terbiasaDeque
.Memang ada banyak kesalahpahaman tentang kutipan ini, jadi yang terbaik adalah mundur dan melihat apa masalah sebenarnya. Masalahnya tidak terlalu banyak sehingga Anda tidak boleh "mengoptimalkan". Karena "mengoptimalkan" bukanlah tugas yang harus Anda lakukan. Anda tidak boleh bangun di pagi hari dan berkata pada diri sendiri "hei, saya harus mengoptimalkan kode hari ini!".
Ini mengarah pada usaha yang sia-sia. Hanya dengan melihat kode dan mengatakan "Aku bisa membuatnya lebih cepat!" mengarah ke banyak upaya membuat sesuatu lebih cepat yang cukup cepat di tempat pertama. Anda mungkin bangga mengatakan pada diri sendiri bahwa Anda membuat sedikit kode empat kali lebih cepat, tetapi jika kode itu adalah perhitungan yang terjadi pada tombol tekan, dan butuh 10 msecs di tempat pertama sebelum ditampilkan ke pengguna manusia, tidak ada yang akan peduli.
Itu adalah "prematur" dalam "optimasi prematur". Kapan itu bukan "prematur"? Ketika pelanggan memberi tahu Anda "ini terlalu lambat, perbaiki!" Saat itulah Anda menggali kode dan mencoba membuatnya lebih cepat.
Ini tidak berarti bahwa Anda harus mematikan otak Anda. Itu tidak berarti bahwa Anda harus menyimpan 10.000 catatan pelanggan dalam daftar yang terhubung sendiri. Anda harus selalu memahami dampak kinerja dari apa yang Anda lakukan dalam pikiran dan bertindak sesuai dengannya. Tetapi idenya adalah bahwa Anda tidak menghabiskan waktu ekstra dengan sengaja mencoba membuatnya lebih cepat. Anda hanya memilih pilihan yang lebih performan dari pilihan lain yang setara.
sumber
Anda dapat melakukan hal-hal dengan cara yang salah, atau melakukan hal-hal dengan cara yang benar.
Seringkali, hal-hal dilakukan dengan cara yang salah dan kode dire-refored sehingga dilakukan dengan cara yang benar. Jika Anda akan menulis kode baru, dan Anda tahu bahwa Anda dapat melakukan hal-hal dengan cara yang benar tanpa penalti besar, saya akan melakukan kesalahan dengan melakukannya dengan cara yang benar. (Perhatikan bahwa, setelah pengujian kinerja, dll, beberapa hal mungkin perlu diubah - tapi tidak apa-apa. Sebagai alternatif, implementasi yang sepenuhnya naif jarang, jika pernah, benar.)
Itu belum tentu optimasi prematur jika Anda a) tahu bahwa itu akan membantu di masa depan atau b) tahu bahwa jalur suboptimal akan menyebabkan masalah di jalan. Ini seperti permainan catur, sungguh.
Saya pikir orang akan cenderung ingin melakukan hal yang benar, daripada melakukan kesalahan. Gunakan ini ketika Anda mendiskusikan strategi alternatif dengan rekan-rekan Anda.
sumber
Ini sepertinya masalah komunikasi dan bukan masalah pemrograman. Cobalah untuk memahami mengapa orang merasakan hal yang mereka lakukan dan mencoba untuk mengkristalkan mengapa Anda berpikir cara Anda akan lebih baik. Ketika Anda sudah melakukan itu, jangan memulai argumen konfrontatif di mana tujuan Anda adalah memberi tahu orang lain mengapa mereka salah dan Anda benar. Jelaskan pikiran dan perasaan Anda dan biarkan orang lain bereaksi terhadapnya. Jika Anda tidak dapat mencapai semacam konsensus dan Anda merasa ini adalah masalah yang sangat kritis, maka Anda mungkin memiliki beberapa masalah serius dalam tim secara keseluruhan.
Lebih fokus pada pemrograman aktual, jangan buang waktu pada argumen panjang atas sesuatu yang Anda hanya punya firasat "lebih cepat". Jika Anda melihat seseorang menulis metode yang disebut sekali per permintaan dalam aplikasi web dan memiliki kompleksitas waktu O (n ^ 2) ketika Anda TAHU itu benar-benar masalah waktu O (log (n)), maka yakinlah, jika memang demikian tidak punya otak, silakan.
Berhati-hatilah, sebagai manusia, kita para programmer benar-benar buruk (dan maksud saya AWFUL) untuk menebak-nebak bagian mana dari aplikasi kita yang akan menjadi hambatan. Eric Lippert menulis tentang subjek yang menarik ini di posting blog ini . Selalu mendukung pemeliharaan. Masalah kinerja apa pun yang akhirnya ditemukan dapat dengan mudah (relatif,) diperbaiki ketika Anda memiliki lebih banyak info.
sumber