Apa yang membuat produk perangkat lunak besar dan kompleks lambat? [Tutup]

16

Untuk alasan yang sebagian besar tidak relevan, saya menginstal Delphi 7 sekali lagi dalam waktu yang lama. Saya harus mengatakan, saya benar-benar terpesona - dengan cara yang belum pernah saya lakukan selama beberapa waktu. Ini bukan bagaimana saya mengingat semuanya. Instalasi membutuhkan waktu sekitar 30 detik. Peluncuran membutuhkan waktu 2 detik, dan langsung dapat digunakan. Saya dapat menekan "Jalankan" yang kedua setelah dimulai, dan kurang dari sedetik kemudian program kosong sudah terlihat dan berjalan. Hore untuk komputer jadi lebih cepat!

Tapi alasan saya terpesona seperti ini adalah karena biasanya saya menggunakan Visual Studio 2010, itu tidak terasa tajam sama sekali. Memang, Delphi 7 adalah sistem yang jauh lebih kecil daripada Visual Studio 2010, tetapi memiliki penampilan memiliki semua hal yang benar-benar diperlukan di sana: palet kontrol, perancang formulir, editor kode dengan pelengkapan kode. Saya menyadari bahwa bahasanya mungkin lebih sederhana, dan penyelesaian kode mungkin jauh kurang kuat, dan IDE mungkin tidak hampir sama extensible dan kaya fitur, tetapi tetap: Saya tidak mengerti bagaimana (yaitu melalui mekanisme apa) tidak memiliki banyak fitur tambahan (yang mungkin belum saya picu) menyebabkan sistem seperti Visual Studio selalu merasa lamban dibandingkan.

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?

Roman Starkov
sumber
7
Sederhana: seiring peningkatan massa, dibutuhkan lebih banyak kekuatan untuk mengatasi kelembaman.
Shog9
Seseorang pernah mengatakan kepada saya manajer tetapi saya tidak percaya sama sekali.
MIchael Grassman
1
Ini adalah sebagian besar alasan saya masih menggunakan D7 untuk pemrograman Delphi.
GrandmasterB
Kode tercepat adalah kode yang tidak pernah dieksekusi.
Henry
4
@romkyns: Saya menemukan banyak perangkat lunak di era modern sering sangat kembung, tidak perlu besar dan berat. Banyak perangkat lunak sekarang memecahkan masalah yang sama yang diselesaikan sepuluh, bahkan dua puluh tahun yang lalu, dengan sebagian kecil dari kekuatan dan ruang. Mengapa masih tertinggal seburuk yang pernah terjadi, jika tidak lebih? Inefisiensi dan mengasapi.
Orbling

Jawaban:

20

Astronautika Arsitektur

Visual Studio 2010 dibangun di atas Windows Presentation Foundation. Lihatlah kelas Button untuk WPF. Ini adalah anak ke-9 dari kelas dasar. Ini memiliki sekitar 5 halaman properti, metode, dan acara. Di belakang layar terdapat lima halaman definisi gaya yang menggambarkan sudut-sudutnya yang bulat indah dan transisi animasi yang halus ketika kursor mouse bergerak di atasnya. Ini semua untuk sesuatu yang secara mendasar menampilkan beberapa teks atau gambar dan menghasilkan acara klik ketika mendeteksi tombol mouse turun.

Hentikan program seperti Visual Studio di sembarang titik. Lihatlah jejak tumpukan. Peluangnya sangat bagus sehingga Anda berada 20 level di dalam tumpukan panggilan dan lima DLL dimuat untuk sampai ke sana.

Sekarang, bandingkan dua hal ini dengan Delphi. Saya yakin Anda menemukan bahwa Tombol Delphi hanya memiliki 20 properti, metode, dan acara. Saya yakin Delphi IDE hanya memiliki jejak jejak 5-7 level. Karena ketika komputer lebih lambat, Anda tidak bisa menggunakan Visual Studio 2010 tanpa IDE membutuhkan waktu 40 menit untuk memulai :-)

Apakah yang satu lebih baik dari yang lain? Yah, saya biasanya dapat memberitahu program Delphi ketika memuat karena terlihat datar, warnanya diredam (8 bit mungkin?), Dan tidak ada naungan atau animasi yang halus. Saya merasa 'murah' belakangan ini. Murah, tapi cepat.

Apakah kita lebih baik? Itu pertanyaan bagi para filsuf, bukan coders.

Jay Beavers
sumber
4
Program delphi tidak terlihat datar. Sebaliknya, seorang programmer memprogram sebuah program agar terlihat datar. Anda dapat membuat antarmuka yang tampak bagus, modern, penuh warna dengan Delphi seperti yang Anda bisa dalam C # atau C ++.
GrandmasterB
2
Ini adalah jawaban yang mendalam; tapi saya tidak yakin itu lengkap. Visual Studio 2008 (pendahulu 2010) tidak memiliki WPF di dalamnya dan masih dunia lebih lambat dari Delphi 7. Apakah Anda masih mengatakan hal yang sama tentang kedalaman tumpukan panggilan dan jumlah DLL yang dimuat?
Timwi
3
@ Timwi Ya, tentu saja saya akan melakukannya. Maksud saya kurang tentang kejahatan WPF (saya suka WPF sebenarnya) dan lebih banyak tentang bagaimana kita cenderung menambahkan lapisan demi lapisan abstraksi perangkat lunak ketika diberi pilihan. Mungkin Visual Studio 2008 tidak memiliki overhead yang cukup banyak, tetapi seperti yang Anda catat itu sudah cukup :-)
Jay Beavers
@ GrandmasterB, saya tidak membanting Delphi karena dilengkapi dengan asumsi yang lebih sedikit dan perpustakaan yang lebih sederhana. WPF dirancang dengan asumsi akselerasi perangkat keras GPU akan memungkinkan program untuk menggunakan warna yang lebih dalam, seringnya animasi, alpha blending, shadows, dll. Delphi direkayasa pada saat asumsi-asumsi ini tidak dapat dibuat. Bisakah Anda menerapkan kembali semua ini di Delphi? Tentu, tetapi Anda harus memasukkan banyak kode hanya untuk mendapatkan perilaku tombol WPF. Di sisi positifnya, tombol Delphi tidak datang dengan persyaratan CPU, memori, dan GPU, tombol WPF memiliki salah satu yang merupakan pertanyaan @ OP.
Jay Beavers
10
Argumen Anda untuk UI datar dan polos sepenuhnya tidak valid oleh UI 'Modern' baru Windows 10. Sekarang kita memiliki semua overhead untuk membuat tombol datar, persegi, polos seperti yang kita miliki 30 tahun yang lalu.
gbjbaanb
11

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 Pixelatau Boolean.

Namun saya melihat banyak kode sumber untuk program-program yang menangani beban berat (mis: berurusan dengan ratusan ribu hingga jutaan Pixelatau 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.

Thomas Owens
sumber
2
Utang teknis, dengan kata lain. Hutang teknis yang tidak pernah lunas.
Robert Harvey
1
Robert benar. Satu kesalahan dari seorang pria, dua ratus kesalahan --forceoleh manajer yang berteriak "Anda akan dipecat jika Anda tidak menerapkannya besok" yang menerbangkan praktik-praktik rekayasa perangkat lunak, TDD, pengujian unit yang baik, dan prinsip pemrograman manusia dan waras apa pun. , ditambah dua kali Anda lelah .. orang yang membuat perusahaan itu marah karena dia diberhentikan tanpa alasan dan mengacaukan basis kode .. perpustakaan yang dihentikan itu tidak pernah Anda perbarui ... dan di sini Anda memilikinya: kode spaghetti lezat dan perangkat lunak yang membengkak. Bon appetit
user3834459
2
Menarik, terutama dalam bagaimana Anda telah melihat granularity berlebihan disalahgunakan. Saya menemukan diri saya melakukan hal serupa pada kesempatan di masa lalu dan hasilnya buruk. Ini sangat mirip dengan jawaban Anda dari beberapa hari yang lalu tentang menggunakan koleksi dan algoritma massal dalam preferensi daripada granularitas berlebihan . Saya tidak percaya bahwa jawaban itu tidak lebih dihargai karena kedalamannya. Itu membuat saya memikirkan kembali beberapa desain yang telah saya buat selama bertahun-tahun. Saya bertanya-tanya mengapa teknik-teknik itu tidak dipromosikan secara luas?
Mike Mendukung Monica
2
@ Mike Saya sedikit catatan rusak ketika mencoba untuk mempromosikan lebih banyak pola pikir yang berorientasi data. Ini populer di industri game di mana mereka mencoba memanfaatkan setiap inci perangkat keras. Yang mengatakan, memang diakui mengurangi fleksibilitas. Jika Anda memiliki kelas piksel abstrak, Anda dapat melakukan hal-hal gila dengan itu seperti memiliki satu gambar yang menggabungkan dua atau lebih format piksel yang berbeda! Namun ketika kita berhadapan dengan jalur kritis, mungkin tidak ada gambar yang akan mendapat manfaat dari tingkat fleksibilitas itu, dan kinerja mulai menjadi perhatian nyata dengan apa pun yang melibatkan gambar dan piksel.
1
Di masa lalu yang buruk saya menerapkan beberapa kode untuk mem-bypass API grafik dan secara langsung mengakses piksel dalam memori untuk bagian penting dari kode saya. Perbedaan antara banyak lapisan abstraksi dan akses langsung adalah sekitar 100x, yang penting di komputer pada masa itu. Sekarang komputer Anda cukup cepat sehingga Anda dapat bekerja keras dengan abstraksi berapapun jumlahnya, jika perlu.
Michael Shopsin