Dengan otak kemanusiaan saya, saya selalu berpikir seperti ini - jika seorang programmer tahu bagaimana membuatnya lebih berkinerja, maka itu perlu untuk membuatnya lebih berkinerja. Solusi produktif = solusi yang tepat. Satu bahasa pemrograman mungkin lebih lambat dari yang lain, dan jika ternyata, bahasa pemrograman tersebut terbuang percuma.
Nah, yang pasti - jika pengembang adalah spesialis kinerja, dia akan tenggelam untuk semua hal ini, bahkan jika itu salah.
Tentu saja, semua ini tidak masuk akal, tetapi saya tidak berhak memberi tahu Anda tentang hal itu. Oleh karena itu, Andrey Akinshin, seorang pengembang dan ahli matematika, kandidat ilmu fisika dan matematika, pengelola BenchmarkDotNet dan pembuat parfum, penulis buku Pro .NET Benchmarking dan hanya seorang insinyur yang sangat, sangat keren, datang ke podcast kami.
Di bawah ini adalah kutipan yang dipilih.
Tidak mungkin untuk meramalkan semuanya dalam tolok ukur
Seorang kolega saya baru-baru ini memiliki yang berikut ini. Dia memprogram di pagi hari, semuanya baik-baik saja dengannya, semuanya bekerja dengan cepat. Pada titik tertentu, semuanya mulai menempel - Pengendara lambat, IDEA, browser - semuanya lambat. Dia tidak bisa memahami dengan cara apa pun apa yang terjadi? Dan kemudian saya sadar. Dia mengerjakan laptop hitam yang berdiri di dekat jendela. Itu cukup dingin di pagi hari, dan matahari terbit di siang hari, laptop menjadi sangat panas dan mengalami pelambatan termal.
Dia tahu bahwa ada hal seperti itu, mengetahui bahwa lingkungan fisik dapat mempengaruhi kinerja, dan dia segera menyadari apa yang sedang terjadi. Dia memiliki model di kepalanya yang menurutnya dunia berfungsi, dan dalam model ini dia kurang lebih cepat menemukan apa yang sedang terjadi.
Artinya, keterampilan paling penting yang dapat diperoleh dalam pembandingan tidak mengetahui semuanya secara mutlak di semua detail - semua waktu proses dan semua perangkat keras. Hal utama adalah memahami bagaimana Anda perlu bertindak untuk menemukan masalah, sebaiknya secepat mungkin dengan sedikit usaha.
Saya akan memberikan analogi dengan bahasa. Ketika Anda mempelajari bahasa pemrograman fungsional pertama Anda, Anda perlu sedikit mengubah sikap Anda terhadap dunia - untuk memahami prinsip-prinsip pemrograman fungsional, bagaimana Anda umumnya perlu berpikir. Kemudian Anda mengambil bahasa fungsional X berikutnya, dan Anda sudah memiliki prinsip-prinsip ini di kepala Anda. Anda menyaksikan pasangan halo dunia dan mulai menulis juga.
Pada saat yang sama, Anda mungkin tidak mengetahui beberapa nuansa bahasa tersebut. Anda mungkin tidak tahu bagaimana konstruksi sintaksis tertentu bekerja, tapi itu tidak terlalu mengganggu Anda. Anda merasa nyaman dan menulis. Saya menghadapi perilaku yang tidak bisa dipahami - saya membaca manual, mengetahuinya, fakta baru dengan mudah memasuki gambaran Anda tentang dunia, dan Anda melangkah lebih jauh. Dan Anda tidak akan pernah mempelajari semua nuansa dari semua bahasa fungsional di dunia, tetapi pendekatan umum akan tetap ada di kepala Anda.
Saya percaya bahwa Anda perlu mencapai level yang sama di setiap area, dan kemudian melangkah lebih jauh.
Di beberapa titik dalam pembandingan, saya berfokus secara khusus pada akurasi pengukuran, pada fitur runtime tertentu, sepotong besi, dan hal lain. Kemudian saya berhenti menemukan Amerika setiap saat, dan semua masalah kinerja mulai masuk ke dalam kelas yang sudah saya ketahui. Dan saya melangkah lebih jauh - ke arah analisis kinerja: apa yang harus dilakukan dengan angka yang kami ukur. Dan ini adalah bidang di mana saya belum mencapai ambang pengetahuan. Beberapa hal telah menjadi jelas bagi saya, tetapi masih ada pekerjaan besar di depan - untuk memahami bagaimana menerapkan semua ini dalam praktik, rumus mana yang akan digunakan, mana yang tidak digunakan, pendekatan mana yang baik dan mana yang tidak.
Benchmarking untuk kepentingan benchmarking bukanlah hal terbaik untuk dilakukan
Harus selalu ada beberapa persyaratan kinerja bisnis, Anda harus selalu memahami apa yang Anda perjuangkan. Jika Anda tidak memiliki persyaratan bisnis, maka tidak ada gunanya melakukan kinerja juga. Maka dari itu, ketika ada kebutuhan bisnis, Anda sudah mulai memahami pendekatan mana, setidaknya secara kasat mata, yang dapat Anda gunakan dan mana yang tidak. Jika tidak, Anda pergi, patok banding, periksa - pendekatan mana yang sesuai dengan kebutuhan Anda.
Dan ketika Anda memiliki sekumpulan algoritme, opsi untuk menulis kode, desain, dan hal-hal lain, dan semuanya sesuai dengan persyaratan - Anda sudah memilih apa yang akan lebih konsisten dengan proyek lainnya, yang mencerminkan pandangan Anda tentang estetika, tentang cara menulis kode dengan benar ...
Secara kasar, jika saya memiliki maksimal 10 elemen dalam sebuah koleksi, dan ada dua opsi - tulis algoritme sederhana untuk kubus atau yang sangat kompleks untuk n * log n - Saya akan menulis yang sederhana untuk kubus yang akan jelas bagi semua orang, yang akan mudah dirawat dan dimodifikasi. Karena saya mengerti bahwa dia tidak akan pernah menembus batasan performa saya.
Jika Anda menulis solusi lambat untuk kumpulan data kecil, dan kemudian menggunakannya untuk kumpulan data besar, dan tidak memiliki konsekuensi yang sangat buruk (biasanya tidak ada) - baiklah, ayo kita perbaiki. Namun di kepala saya akan ada model bagaimana menghindari kesalahan tersebut dikemudian hari.
Misalnya, Anda bisa meletakkan assert di awal metode sehingga jumlah elemen dalam koleksi tidak melebihi angka ini dan itu. Kemudian programmer berikutnya yang tidak sengaja mencoba menggunakan metode Anda akan segera melihat pengecualian dan tidak akan menggunakannya. Hal-hal seperti itu datang dengan pengalaman.
Ada masalah lain - persyaratan bisnis yang tidak stabil. Mereka pasti akan berubah - ini adalah aksioma dari realitas kita, tidak ada cara untuk menghindar dari ini. Dengan pengalaman, Anda akan dapat memprediksi dengan mata di mana persyaratan dapat berubah, di mana perlu meletakkan tingkat kinerja yang baik, di mana beban dapat meningkat.
Meskipun intuisi ini tidak ada, Anda dapat melalui trial and error dan melihat apa yang terjadi.
Anda selalu memiliki kompromi antara kinerja dan keindahan
Jika Anda menulis seefisien mungkin, kemungkinan besar, kode Anda akan menjadi buruk, menjijikkan - dan bahkan jika Anda menutup mata terhadap estetika, akan sulit untuk mempertahankannya, bug halus akan terus muncul di dalamnya, karena arsitekturnya buruk, kodenya buruk, semuanya buruk.
Saya pikir Anda perlu fokus pada persyaratan bisnis saat ini, dan menulis kode yang paling bersih, paling mudah dipahami, indah, dan dapat dipelihara di dalamnya. Dan pada saat ia mulai menuai (atau ada perasaan bahwa ia akan segera mulai), maka sesuatu telah berubah.
Dan bahkan jika Anda selalu berkonsentrasi hanya pada kinerja, tidak ada yang namanya kode yang dioptimalkan dengan sempurna dan produktif secara maksimal. Itu berarti segalanya - mereka lupa tentang C #, melupakan semua bahasa yang indah. Dan lebih baik menulis secara umum dalam kode mesin, karena Assembler juga dibatasi dalam sintaks. Dan jika Anda segera menulis pada byte, maka Anda akan mendapatkan peningkatan kinerja.
Dalam beberapa kasus, kode tercepat ternyata adalah yang paling indah, paling jelas, paling benar. Tetapi pengorbanan seperti itu pasti muncul dalam puluhan dan ratusan momen kecil. Katakanlah ada hal seperti memeriksa pelanggaran batas array. Anda dapat menyetujui bahwa runtime akan mengurus Anda untuk memeriksa batas-batas larik di semua tempat, dan jika Anda beralih ke elemen pertama minus, Anda akan mendapatkan pengecualian dan Anda tidak akan membaca dari bagian kiri memori.
Dan untuk keyakinan ini bahwa Anda pasti tidak pernah mengurangi bagian memori yang salah - Anda membayar dengan sedikit kinerja. Artinya, kami menggunakan kinerja sebagai sumber daya untuk membuat program lebih stabil, dapat dipahami, dan dapat dipelihara.
Bahasa tidak memiliki properti seperti kinerja
Jika Anda melihat artikel yang X lebih cepat dari Y, Anda bisa menutup artikel tersebut. Bahasa adalah abstraksi matematika. Ini adalah seperangkat aturan yang sesuai dengan program yang dikompilasi. Ini tidak memiliki kinerja, tidak memiliki kinerja, itu adalah sesuatu yang ada di kepala Anda dan diwujudkan dalam editor teks.
Kinerja tersedia untuk waktu proses, lingkungan, program tertentu, dan kera tertentu. Saat Anda memperhitungkan semua faktor ini, Anda dapat berbicara tentang kinerja. Tetapi ada ledakan kombinatorial, dan Anda tidak dapat mengatakan bahwa satu kode dalam bahasa ini selalu lebih cepat daripada kode lain dalam bahasa ini, karena versi baru perangkat keras dan runtime akan segera keluar. Anda tidak akan pernah melalui semua kemungkinan kombinasi faktor eksternal dalam hidup Anda. Apishka yang Anda gunakan pada dasarnya berbeda.
Misalnya, dalam bahasa bersyarat di tahap awal pengembangan, mereka menerapkan metode pengurutan menggunakan gelembung. Yah, saya tidak tahu - orang-orang ingin meluncurkan rilis sesegera mungkin, menulis penyortiran paling sederhana yang dapat mereka lakukan. Anda mengambilnya, menggunakan metode ini, dan ternyata lebih lambat pada big data daripada di bahasa lain di mana quicksort dilakukan. Apakah ini berarti Anda dapat berbicara tentang kinerja beberapa bahasa? Tidak. Anda dapat mengatakan bahwa kera khusus ini dari bahasa ini di sistem operasi ini, pada perangkat keras ini, di lingkungan ini, bekerja lebih lambat daripada kera lain dari bahasa lain di lingkungan lain. Jadi bisa dibilang. Tapi itu akan menjadi paragraf teks yang sangat panjang untuk dirumuskan dengan benar.
Secara konvensional, kita dapat mengatakan bahwa C ++ lebih cepat dalam banyak kasus daripada JavaScript. Tetapi akan lebih tepat untuk mengatakan bahwa programmer C ++ dengan pengalaman C ++ yang baik yang menulis dalam C ++ akan menulis program yang mungkin lebih cepat daripada JavaScript javascriptor akan menulis sesuatu yang akan berfungsi di browser.
Tapi ada juga banyak reservasi di sini. Tetapi bagaimana jika seorang pria yang menulis dalam JavaScript mengatakan bahwa itu tidak benar, dan pergi ke sana untuk beberapa jenis WebAssembly atau sesuatu yang lain untuk diulang. Atau temukan di GitHub sebuah superinterpreter-compiler JavaScript yang bekerja dengan subset JS yang terpotong oleh tiga setengah konstruksi sintaks, tetapi menghasilkan kode native super cepat.
Dan di sana, jika mau, Anda dapat menulis kode yang akan mengambil alih C ++. Selain itu, Anda dapat menulis kompiler JavaScript Anda sendiri, yang akan dirancang untuk mengkompilasi satu program dan mengambil alih "plus" dalam kecepatan. Dan ini, pada prinsipnya, adalah opsi yang valid.
Tekanan sosial dari proyek open source yang populer
Dengan pertumbuhan dan popularitas proyek, muncul tingkat tanggung jawab tertentu. Tetapi Anda tidak benar-benar memiliki kewajiban. Fakta ini tidak selalu mudah untuk dipahami, terutama ketika semua jenis orang datang ke GitHub dan berkata: “Saya tidak bekerja di sini! Segera perbaiki! Saya sangat membutuhkan ini untuk bekerja. Pergi dan perbaiki! " Atau seorang pria mendapat pekerjaan dan saya sedang berlibur. Tiga atau empat hari berlalu, saya bahkan tidak melihat bahwa dia memulai sesuatu di sana. Saya sedang beristirahat di suatu tempat, dan pria itu mulai - “Kenapa kamu tidak menjawab saya? Komunitas macam apa yang dimiliki proyek ini?! Anda umumnya semua orang yang menjijikkan, Anda harus melakukan hal-hal buruk dengan Anda! Saya menyia-nyiakan waktu saya, menulis kepada Anda bahwa Anda salah, dan Anda tidak melakukan apa-apa sama sekali, Anda telah mengabaikan saya selama empat hari! Bagaimana mungkin ?! "
Dan semakin populer proyeknya, semakin banyak tekanan sosial dari orang-orang yang percaya bahwa open source adalah tempat orang lain melakukan pekerjaan Anda untuk Anda secara gratis. Tapi sebenarnya tidak.
Dan sekarang, ketika kekebalan muncul terhadap orang yang menginginkan sesuatu dari Anda, maka hidup menjadi lebih mudah. Sekarang saya masuk ke BenchmarkDorNet ketika saya punya waktu dan mood untuk membuat kode. Saya tahu ada banyak bug di sana. Mereka sebagian besar tidak kritis, dan menyangkut beberapa jenis kasus marjinal - dalam lingkungan ini dan itu dengan pratinjau terbaru dari DotNet kelima, sesuatu di suatu tempat tidak berfungsi. Baiklah, biar tidak berhasil. Saat saya sedang mood, saya akan pergi dan memperbaikinya.
Jika orang lain membutuhkannya, mereka dapat memperbaikinya sendiri dan mengirim permintaan tarik - Saya akan melakukan peninjauan ketika saya punya waktu dan suasana hati.
Tonton seluruh podcast di sini .