Bagaimana saya menghindari "Intuisi Optimasi Buruk Pengembang"?


22

Saya melihat pada sebuah artikel yang mengemukakan pernyataan ini:

Pengembang suka mengoptimalkan kode dan dengan alasan yang bagus. Sangat memuaskan dan menyenangkan. Tetapi mengetahui kapan mengoptimalkannya jauh lebih penting. Sayangnya, pengembang umumnya memiliki intuisi yang mengerikan tentang di mana sebenarnya masalah kinerja dalam suatu aplikasi.

Bagaimana cara pengembang menghindari intuisi buruk ini? Apakah ada alat yang bagus untuk menemukan bagian mana dari kode Anda yang benar-benar membutuhkan pengoptimalan (untuk Java)? Apakah Anda tahu beberapa artikel, kiat, atau bacaan yang bagus tentang hal ini?


1
Ini berujung pada "Bagaimana saya menghindari [mengandalkan] pada intuisi [ketika membuat keputusan]?" Sederhana: Anda memverifikasi dengan fakta dan data yang sulit. Jadi, dalam hal optimasi, dari perspektif pengembang: Anda melakukan benchmark.
haylem

Jawaban:


44
  • Gunakan profiler yang baik untuk mengidentifikasi metode yang mahal.
  • Dokumentasikan berapa lama waktu hot spot sebenarnya berlangsung.
  • Tulis implementasi hot spot yang lebih cepat
  • Dokumentasikan berapa lama hot spot sekarang, semoga tidak membuat mereka hotspot lagi.

Pada dasarnya Anda harus dapat membuktikan kepada orang lain di mana masalahnya, dan bahwa perubahan ini membuatnya hilang.

Karena tidak dapat membuktikan peningkatan, memenuhi syarat - menurut pendapat pribadi saya - untuk segera dikembalikan ke versi aslinya.


51
Atau lebih sederhana lagi: "Untuk menghindari intuisi optimasi yang buruk, jangan gunakan intuisi. Ukur."
Kyralessa

6
Itu sebabnya jawaban Anda adalah milik saya dan saya hanya komentar. : P
Kyralessa

2
@ Thomas, jika Anda mengutak-atik keterbacaan dan pemeliharaan Anda tidak benar-benar melihat masalah kinerja, bukan?

3
@ Thomas, saya tidak setuju. Bahkan dalam spec, Anda perlu menguji ulang kode baru secara menyeluruh. Ini tidak diperlukan untuk kode lama. Kembali.

2
@ Thorbjørn Setelah penyetelan kinerja, Anda juga perlu menguji ulang kode baru secara menyeluruh. Menghemat waktu atau memori tidak ada artinya jika Anda memperkenalkan cacat.
Thomas Owens

10

Satu-satunya cara untuk mengetahui di mana mengoptimalkan adalah dengan membuat profil kode Anda. Alih-alih membuat perubahan yang menurut Anda akan memberikan manfaat, ketahui pasti di mana kode berkinerja terburuk itu dan mulailah dari sana.

Java membuat ini sangat mudah dengan alat VisualVM , yang telah dibundel dengan rilis Java Development Kit (JDK) baru-baru ini. Idenya adalah untuk mengetahui metode mana yang paling banyak disebut dan di mana metode mana Anda menghabiskan sebagian besar waktu Anda, baik dalam kode Anda dan di perpustakaan eksternal. Anda juga bisa mendapatkan data kinerja pengumpulan sampah sehingga Anda dapat menyetel kolektor dan menyesuaikan ruang tumpukan min / maks yang diperlukan oleh aplikasi Anda.


VisualVM tidak ada di JRE, hanya JDK.

1
@ Thorbjørn Ravn Andersen Panggilan bagus. Saya harus mengklarifikasi. Namun, jika Anda melakukan pengembangan Java, Anda biasanya sudah menginstal JDK (walaupun Anda mungkin menjalankan OpenJDK atau serupa - saya tidak tahu apakah itu datang dengan VisualVM).
Thomas Owens

1
Saya sangat sering mengganti ruang kerja di Eclipse yang kemudian default ke JRE yang meluncurkan Eclipse. Karena jauh lebih mudah untuk menginstal JRE daripada JDK, kami perlahan-lahan bermigrasi ke proses pembuatan semut yang mencakup kompiler Eclipse dan karenanya dapat dijalankan pada JRE biasa. Oleh karena itu, hari ini Anda benar-benar dapat melakukan pekerjaan nyata tanpa JDK. VisualVM dapat diunduh secara terpisah sehingga lebih mudah digunakan dengan Java versino yang diberikan, seperti pada Windows 64-bit JVM tidak dapat terhubung ke JVM 32-bit dan sebaliknya.

9

Karena siapa pun di sini berbicara tentang profiler, saya akan fokus pada bagian pertanyaan ini.

Bagaimana cara pengembang menghindari intuisi buruk ini?

Kamu. melakukan. tidak. Sebaliknya Anda tidak pernah mengoptimalkan sejak dini .
Ulangi lagi dan lagi dan lagi, karena ini adalah mantra agama.

Anda akan menemukan diri Anda melakukan itu dan akan menemukan bahwa Anda seharusnya tidak melakukannya.
Dan lagi.
Dan lagi.

Optimalisasi Dini adalah salah satu dosa besar pemrogram .

Alat dan barang adalah bagian dari optimasi nanti yang merupakan kerajinan mapan .


Optimasi awal "kode berbelit-belit", pasti. Memilih algoritma dan / atau struktur data yang sesuai dengan masalah Anda dan (dengan beban pemrosesan yang diharapkan) memiliki karakteristik kinerja yang baik adalah sesuatu yang harus dilakukan sebelum Anda mulai menulis kode.
Vatine

@Vatine Ya, sudah ada. Tidak, jangan. Lakukan apa yang sesuai dengan peta pikiran Anda dari masalah yang dihadapi. Ini bisa menjadi algoritma yang paling performan , dan saya harap Anda tidak perlu melakukannya.
ZJR

kedengarannya bagi saya sebagai prinsip YAGNI - Anda TIDAK AKAN Membutuhkannya!
EL Yusubov

7

Alat-alat ini disebut profiler . Anda dapat menggunakannya untuk benar-benar mengukur bagian mana dari program Anda yang membutuhkan waktu paling lama untuk dieksekusi, jadi ke mana harus memfokuskan upaya penyetelan Anda.

Sama pentingnya untuk mengukur lagi setelah perubahan, untuk memverifikasi bahwa perubahan Anda memiliki efek yang diinginkan.


5

Lihat juga berapa banyak memori yang digunakan program Anda, bukan hanya kecepatan atau runtime-nya.

Banyak pembuat kode yang bekerja dengan bahasa yang dikumpulkan sampah seperti Java berada di bawah kesan yang salah bahwa pengumpulan sampah mencegah kebocoran memori. Bukan itu masalahnya. Jika Anda memegang referensi ke objek yang tidak Anda butuhkan lagi, itu tidak akan dikumpulkan, sehingga akan bocor.

Saya telah melihat aplikasi web Java yang sangat bocor sehingga mereka akan menjalankan server mereka dari ruang swap!

Jika Anda menggunakan kedua profiler runtime dan beberapa jenis profiler memori, Anda akan belajar menulis kode lebih cepat dan lebih ramping secara intuitif. Ini memiliki efek bahwa kode Anda lebih cenderung berjalan cepat pada percobaan pertama.


1

obat saya adalah memulai dengan mendapatkan jawaban yang jelas untuk dua pertanyaan:

  1. bagaimana mengukur kinerja (mis. mengukur waktu pengambilan data )
  2. berapa nilai target (mis. data dimuat dalam 3 detik atau kurang dengan kepercayaan 95% )

Pelajari trik di atas dari kawan-kawan tim harimau yang pernah diundang untuk menyimpan produk kami yang rusak. Rilis itu rusak karena alasan kinerja, itu bisa membuat pelanggan strategis perusahaan longgar yang membenarkan keterlibatan orang-orang harimau (btw cukup mahal). Saya ditugaskan untuk membantu mereka dalam menjelaskan rincian proyek; juga menggunakan ini sebagai kesempatan untuk belajar sedikit tentang kinerja.


1

Apa yang saya temukan adalah penangkal terbaik untuk optimasi prematur adalah metode ini .

Setelah Anda menggunakannya untuk mempercepat beberapa kode (seperti dalam contoh ini ), itu menjadi kecanduan sendiri, dan Anda memahami prinsip pertama penyetelan kinerja bukan kode tweaker, itu menemukan masalahnya .

Optimalisasi sebenarnya adalah optimalisasi prematur karena berburu untuk memberi makan keluarga Anda adalah dengan menembak kaleng. Ini semua tentang menemukan tambang.


1
Dan sayangnya, Anda hanya dapat membawa 200 pound kembali ke keluarga Anda, jadi jangan tembak bajing sepanjang hari.
Jordan

1

Pertanyaan lama, tetapi saya akan menawarkan jawaban ini yang sangat berbeda dari yang lain.

Peluang besar untuk keuntungan kinerja berasal dari pemrosesan paralel. Cobalah untuk merancang kode Anda untuk memanfaatkan banyak utas. (Bahkan jika, untuk kesederhanaan, Anda tidak melakukannya di versi 1). Diperlukan sedikit dugaan atau intuisi.

Yang lainnya adalah optimasi prematur, dan membutuhkan intuisi Anda, yang seringkali salah.


Poin yang sangat bagus. Kembali pada hari itu, Anda dapat mengandalkan prosesor yang semakin cepat setiap beberapa tahun. Sekarang Anda seharusnya hanya berharap bahwa akan ada lebih banyak prosesor.
JimmyJames

0

Intuisi Anda dapat meningkat seiring waktu. Saya akan membuang itu, mungkin sedikit kontroversial, tetapi selama bertahun-tahun menggunakan VTune dan CodeAnalyst dan sekarang CodeXL, saya akan mengatakan saya jauh lebih akurat dalam intuisi saya daripada sebelumnya tentang di mana hotspot akan berada, setidaknya untuk titik di mana saya tidak lagi benar-benar lengah ketika saya profil beberapa kode. Itu tidak berarti saya berusaha mengoptimalkan berbagai hal secara membabi buta.

Profiling sebenarnya telah meningkatkan ketergantungan saya pada profiler, tidak mengurangi itu. Saya hanya mengatakan bahwa saya dapat dengan lebih mudah mengantisipasi apa yang akan terjadi pada profil dan sampai batas tertentu, berhasil menghilangkan hotspot dan meningkatkan waktu yang dibutuhkan untuk menyelesaikan operasi pengguna akhir tanpa mengambil tikungan buta dalam gelap dan hilang (sesuatu yang Anda dapat melakukan bahkan ketika menggunakan profiler sampai Anda mulai memahami tidak hanya apa hotspot itu, tetapi mengapa mereka hotspot sehubungan dengan, katakanlah, cache misses).

Namun, baru setelah saya mulai menggunakan profiler saya mulai meningkatkan intuisi itu. Salah satu alasannya adalah karena jika Anda terbiasa dengan kode Anda, firasat Anda mungkin benar sehubungan dengan hotspot terbesar dan paling jelas, tetapi tidak semua kehalusan di antaranya. Tentu saja jika Anda memiliki operasi pengguna-akhir yang membutuhkan waktu satu jam untuk menyelesaikan dan ada satu algoritma kompleksitas kuadratik menganga memproses input yang mencakup seratus ribu elemen, Anda mungkin bisa keluar dengan kaya mempertaruhkan seluruh tabungan seumur hidup Anda dengan gagasan bahwa itu adalah kompleksitas kuadratik Algoritma salah di sini. Tetapi itu tidak memberi Anda wawasan terperinci atau, katakanlah, beri tahu Anda dengan pasti apa yang tidak berkontribusi pada waktu itu.

Ada begitu banyak nilai yang bisa didapat ketika Anda mulai membuat profil dan melihat di mana semua hal yang Anda pikir mungkin menjadi kontributor waktu yang lebih besar tidak berkontribusi banyak waktu; bukan sumber-sumber inefisiensi yang menganga tetapi yang Anda curigai mungkin sedikit tidak efisien tetapi, setelah diprofilkan, menyadari bahwa mereka nyaris tidak berkontribusi kapan saja. Dan itu berpotensi di mana Anda memperoleh wawasan paling intuitif adalah menemukan diri Anda ditampilkan salah di semua area halus di mana tidak jelas berapa banyak waktu yang dihabiskan.

Intuisi manusia di luar kerumitan algoritmik yang jelas seringkali akan mulai salah karena apa yang efisien untuk mesin dan apa yang efisien bagi pikiran manusia sangat berbeda. Awalnya tidak begitu intuitif untuk berpikir tentang hierarki memori dari register ke cache CPU ke DRAM ke disk. Itu tidak datang secara intuitif untuk berpikir bahwa aritmatika redundan mungkin lebih cepat daripada melakukan lebih banyak percabangan atau akses memori dari tabel pencarian untuk melewati beberapa pekerjaan pemrosesan. Kita cenderung berpikir dalam hal berapa banyak pekerjaan yang harus dilakukan sambil mendiskontokan hal-hal seperti biaya pengambilan keputusan dan memori serta penyimpanan. Apa yang efisien untuk perangkat keras sering sangat kontra-intuitif dengan cara yang akan mematahkan semua asumsi manusia Anda mulai,

Di mana meningkatkan intuisi dapat membantu, melalui pembuatan profil, adalah desain antarmuka . Desain antarmuka sangat mahal untuk diubah jika ditinjau kembali, dengan biaya yang meningkat secara proporsional dengan jumlah tempat tergantung pada antarmuka itu. Ketika Anda mulai meningkatkan intuisi Anda, Anda dapat mulai merancang antarmuka yang lebih baik pertama kali dengan cara yang meninggalkan ruang bernapas untuk optimasi di masa depan tanpa perubahan desain yang mahal. Namun sekali lagi, intuisi itu adalah sesuatu yang biasanya Anda kembangkan, dan terus kembangkan tanpa batas, dengan selalu memiliki profiler itu di tangan.


0

Profiler membantu memperbaiki intuisi buruk ketika datang ke kode. Mengingat seberapa banyak perangkat keras yang diprediksi akhir-akhir ini, tidaklah praktis secara manusiawi untuk memprediksi kinerja kode Anda, tetapi itu masih benar dalam masa Knuth, begitu banyak dekade yang lalu yang menganjurkan bahwa pembuat profil harus dimasukkan sebagai bagian dari alat standar untuk pengembangan untuk memperbaiki sifat "sen dolar-dan-pon bodoh" pengembang. Tapi saya akan pergi ke rute yang sangat berbeda dengan jawaban ini mengingat betapa komprehensifnya jawaban dalam hal lain dan mengatakan pemahaman pengguna akhir adalah "perbaikan" lainnya.

Saya telah menyaksikan, dalam pengalaman pribadi saya, pengembang yang sangat brilian (tetapi dengan titik-titik buta yang menganga tentang bagaimana pengguna benar-benar menggunakan perangkat lunak) mengoptimalkan algoritma subdivisi dengan profiler di tangan (yang sangat bagus dan mahal dan komprehensif: Intel VTune dengan grafik panggilan) pengambilan sampel di atas profiler GPU) untuk jerat mencapai hasil yang luar biasa dengan miliaran sisi pada GPU ketika membagi primitif sederhana seperti kubus dengan 6 keramba / poligon input. Kecuali dia menyetel dan menyetelnya pada test case yang tidak seperti case use di dunia nyata (pengguna tidak ingin satu miliar faset menjadi kubus yang terbagi mulai menyerupai bola sempurna, input subdivisi mereka cenderung seperti benda dan kendaraan) dan input kompleks lainnya).

Lucunya, saya mendapatkan lebih jauh dengan otak setengah berfungsi seperti dia dan tidak ada gelar PhD dalam karier saya hanya karena alasan bahwa saya mengerti apa yang diinginkan pengguna, apa yang diinginkan pemasaran, apa yang diinginkan desainer. Saya tidak dapat benar-benar menekankan betapa bermanfaatnya untuk dapat menempatkan diri Anda dalam pola pikir dan posisi pengguna dan melihat perangkat lunak Anda dan apa yang perlu dilakukan sebagai pengguna Anda yang sebenarnya sambil berusaha untuk menceraikan diri Anda dari upaya yang Anda lakukan. untuk membangun apa yang Anda bangun dan melihatnya dengan sepasang mata yang segar. Saya bahkan menemukan dari pengembang di atas bahwa ini adalah hal yang mustahil dilakukan; dia pikir saya bersalah karena memiliki ego yang serupa dengan yang dimiliki semua pengembang yang mengerti teknis tetapi tidak sadar pengguna, dan saya terus membuktikannya salah ketika pengguna dan desainer berbondong-bondong ke saya untuk berbicara tentang apa yang harus dilakukan. Kedengarannya sangat egois tapi saya akan menyeimbangkannya dengan penafian bahwa saya bukan pembuat kode yang brilian, tapi saya mengerti apa yang diinginkan pengguna dan desainer, dan itu membuat saya lebih disukai di bidang saya di mana ini sepertinya sangat jarang kualitas untuk beberapa alasan. Sebagai pemrogram, kita mungkin lebih terbiasa melakukan tes daripada memahami dan bersosialisasi dengan orang-orang biasa yang non-teknis.

Jadi ada profil dan pengukuran yang tepat tetapi ada juga kebutuhan mendasar untuk benar-benar memastikan Anda mengukur operasi dengan jenis input yang benar-benar akan diberikan oleh pengguna dunia nyata ke aplikasi. Kalau tidak, Anda bahkan dapat memiliki VTune atau CodeAnalyst atau gprof atau profiler lain di tangan dan masih, sambil mencoba mengoptimalkan hotspot terhadap apa yang tampak seperti kasus uji normal untuk pengembang tetapi yang tidak jelas bagi pengguna, akhirnya pesimisasi kasus penggunaan umum mendukung beberapa kasus penggunaan yang tidak jelas yang beberapa pengguna, jika ada, pernah mempertimbangkan untuk mendaftar.

Pada akhirnya, semua ketidak praktisan cenderung kita bawa karena pengembang dapat diseimbangkan dengan palu besi dari apa yang membuat pengguna benar-benar cukup bahagia tanpa menyelesaikan kelaparan dunia, dan kebutuhan praktis untuk mendapatkan uang sehingga kita dapat membayar sewa atau membeli bir atau lihat wanita telanjang atau apa pun yang ingin / perlu Anda lakukan. Segala sesuatu yang lain berpotensi melawan kebutuhan bisnis mendasar itu, dan pengembang mana pun begitu mulia, begitu heroik, sehingga lupa bahwa ini adalah tentang menghasilkan uang dan pada akhirnya memuaskan pengguna untuk membuat mereka membayar, mungkin lebih baik membawa dirinya turun ke bumi dan mematikan mode dewa menciptakan dunia virtual demi kebutuhan dunia nyata untuk hanya mengirim dan mendapatkan uang untuk makanan. Kita bisa tersesat dalam metrik dan praktik perangkat lunak tetapi pada dasarnya itu '

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.