Saya ingin bertanya kepada orang-orang yang berpengalaman dalam bekerja dengan sistem skala Visual Studio: apa yang membuat mereka lambat? Apakah itu lapisan demi lapisan abstraksi yang diperlukan untuk menjaga basis kode dalam kemampuan pemahaman manusia? Apakah ini jumlah kode yang harus dijalankan? Apakah ini kecenderungan modern terhadap pendekatan hemat waktu programmer dengan biaya (sangat besar) di siklus clock / departemen penggunaan memori?
Saya pikir Anda menebak beberapa dari mereka tetapi saya ingin menawarkan apa yang saya anggap sebagai faktor terbesar, setelah bekerja pada basis kode yang cukup besar (tidak yakin apakah itu sebesar Visual Studio - berada dalam jutaan baris kode kategori dan sekitar seribu plugin) selama sekitar 10 tahun dan mengamati fenomena yang terjadi.
Ini juga sedikit kurang kontroversial karena tidak masuk ke API atau fitur bahasa atau hal seperti itu. Itu berhubungan dengan "biaya" yang dapat memicu perdebatan daripada "pengeluaran", dan saya ingin fokus pada "pengeluaran".
Koordinasi dan Warisan yang Longgar
Apa yang saya amati adalah bahwa koordinasi yang longgar dan warisan yang lama cenderung menyebabkan banyak akumulasi limbah.
Sebagai contoh, saya menemukan sekitar seratus struktur percepatan dalam basis kode ini, banyak di antaranya berlebihan.
Kami ingin pohon KD untuk mempercepat satu mesin fisika, yang lain untuk mesin fisika baru yang sering berjalan secara paralel dengan yang lama, kami akan memiliki lusinan implementasi octrees untuk berbagai algoritma mesh, pohon KD lain untuk rendering , memetik, dll. dll. Ini semua adalah struktur pohon besar dan besar yang digunakan untuk mempercepat pencarian. Masing-masing individu dapat mengambil ratusan megabita hingga gigabita memori untuk input berukuran sangat rata-rata. Mereka tidak selalu dipakai dan digunakan sepanjang waktu, tetapi pada waktu tertentu, 4 atau 5 dari mereka mungkin ada dalam memori secara bersamaan.
Sekarang semua ini menyimpan data yang sama persis untuk mempercepat pencarian mereka. Anda dapat membayangkannya seperti basis data lama analog yang menyimpan semua bidangnya ke dalam 20 peta / kamus / kamus berlebih yang sekaligus, diorganisasikan secara identik dengan kunci yang sama, dan mencari semuanya sepanjang waktu. Sekarang kami mengambil 20 kali memori dan pemrosesan.
Selain itu, karena redundansi, ada sedikit waktu untuk mengoptimalkan salah satu dari mereka dengan label harga pemeliharaan yang menyertainya, dan bahkan jika kita lakukan, itu hanya akan memiliki 5% dari efek idealnya.
Apa yang menyebabkan fenomena ini? Koordinasi yang longgar adalah penyebab nomor satu yang saya lihat. Banyak anggota tim sering bekerja di ekosistem mereka yang terisolasi, mengembangkan atau menggunakan struktur data pihak ketiga, tetapi tidak menggunakan struktur yang sama yang digunakan anggota tim lainnya bahkan jika mereka merupakan duplikat terang-terangan dari masalah yang sama persis.
Apa yang menyebabkan fenomena ini bertahan? Warisan dan kompatibilitas adalah penyebab nomor satu yang saya lihat. Karena kami sudah membayar biaya untuk mengimplementasikan struktur data ini dan sejumlah besar kode bergantung pada solusi ini, seringkali terlalu berisiko untuk mencoba menggabungkannya ke struktur data yang lebih sedikit. Meskipun banyak dari struktur data ini sangat berlebihan secara konseptual, mereka tidak selalu mendekati identik dalam desain antarmuka mereka. Jadi, menggantinya akan menjadi perubahan besar dan berisiko dibandingkan membiarkan mereka menghabiskan memori dan waktu pemrosesan.
Efisiensi Memori
Biasanya penggunaan dan kecepatan memori cenderung terkait pada tingkat curah setidaknya. Anda sering dapat melihat perangkat lunak lambat dengan cara memonopoli memori. Tidak selalu benar bahwa lebih banyak memori mengarah ke perlambatan, karena yang penting adalah memori "panas" (memori apa yang sedang diakses sepanjang waktu - jika suatu program menggunakan muatan kapal tetapi hanya 1 megabyte dari itu yang digunakan semua waktu, maka itu bukan masalah besar kecepatan-bijaksana).
Jadi, Anda dapat melihat potensi babi berdasarkan penggunaan memori banyak waktu. Jika suatu aplikasi membutuhkan puluhan hingga ratusan megabita memori pada saat startup, itu mungkin tidak akan menjadi sangat efisien. Puluhan megabyte mungkin tampak kecil ketika kita memiliki DRAM gigabyte hari ini, tetapi cache CPU terbesar dan paling lambat masih dalam jangkauan megabita yang sangat sedikit, dan yang tercepat masih dalam kisaran kilobyte. Akibatnya, sebuah program yang menggunakan 20 megabyte hanya untuk memulai dan tidak melakukan apa-apa sebenarnya masih menggunakan cukup "banyak" memori dari sudut pandang cache CPU perangkat keras, terutama jika semua 20 megabyte memori itu akan diakses berulang kali dan sesering program sedang berjalan.
Larutan
Bagi saya, solusinya adalah mencari tim yang lebih terkoordinasi dan lebih kecil untuk membangun produk, yang dapat melacak "pengeluaran" mereka dan menghindari "membeli" barang yang sama berulang-ulang.
Biaya
Saya akan masuk ke sisi "biaya" yang lebih kontroversial hanya sedikit dengan fenomena "pengeluaran" yang telah saya amati. Jika suatu bahasa akhirnya datang dengan label harga yang tak terhindarkan untuk suatu objek (seperti yang memberikan refleksi runtime dan tidak dapat memaksa alokasi yang berdekatan untuk serangkaian objek), tag harga itu hanya mahal dalam konteks elemen yang sangat granular, seperti tunggal Pixel
atau Boolean
.
Namun saya melihat banyak kode sumber untuk program-program yang menangani beban berat (mis: berurusan dengan ratusan ribu hingga jutaan Pixel
atau lebih Boolean
) membayar biaya itu pada tingkat granular.
Pemrograman berorientasi objek dapat memperburuk itu. Namun itu bukan biaya "objek" per se atau bahkan OOP yang salah, itu hanya karena biaya tersebut dibayarkan pada tingkat granular elemen kecil yang akan dipakai oleh jutaan orang.
Jadi itulah fenomena "biaya" dan "pengeluaran" lainnya yang saya amati. Biayanya adalah uang, tetapi uang bertambah jika kita membeli satu juta kaleng soda secara individu alih-alih bernegosiasi dengan produsen untuk pembelian dalam jumlah besar.
Solusi di sini untuk saya adalah pembelian "massal". Objek sama sekali baik-baik saja bahkan dalam bahasa yang memiliki beberapa label harga untuk masing-masing asalkan biaya ini tidak dibayar satu juta kali lipat lebih untuk setara analog kaleng soda.
Optimalisasi Dini
Saya tidak pernah menyukai kata-kata Knuth yang digunakan di sini, karena "optimasi prematur" jarang membuat program produksi dunia nyata berjalan lebih cepat. Beberapa orang menafsirkan itu sebagai "mengoptimalkan awal" ketika Knuth lebih berarti "mengoptimalkan tanpa pengetahuan / pengalaman yang tepat untuk mengetahui dampak sebenarnya pada perangkat lunak." Jika ada, efek praktis dari pengoptimalan prematur sejati sering kali akan membuat perangkat lunak lebih lambat , karena penurunan dalam pemeliharaan berarti hanya ada sedikit waktu untuk mengoptimalkan jalur kritis yang benar - benar penting .
Ini adalah fenomena terakhir yang saya amati, di mana pengembang mencapai untuk menghemat uang pada pembelian satu kaleng soda, tidak pernah lagi untuk dibeli, atau lebih buruk lagi, sebuah rumah, menghabiskan semua waktu mereka mencubit uang receh (atau lebih buruk, uang imajiner dari gagal memahami kompiler atau arsitektur perangkat keras mereka) ketika ada miliaran dolar yang dihabiskan dengan sia-sia di tempat lain.
Waktu sangat terbatas sehingga mencoba untuk mengoptimalkan yang absolut tanpa memiliki informasi kontekstual yang tepat sering membuat kita kehilangan kesempatan untuk mengoptimalkan tempat-tempat yang benar-benar penting, dan dengan demikian, dalam hal efek praktis, saya akan mengatakan bahwa "optimasi prematur membuat perangkat lunak jauh lebih lambat. "
Masalahnya adalah bahwa ada tipe pengembang yang akan mengambil apa yang saya tulis di atas tentang objek dan mencoba untuk menetapkan standar pengkodean yang melarang pemrograman berorientasi objek atau sesuatu yang gila semacam itu. Optimalisasi yang efektif adalah prioritas yang efektif, dan itu benar-benar tidak berharga jika kita tenggelam dalam lautan masalah pemeliharaan.