Saya telah mempertimbangkan untuk menggunakan Lazy<T>
properti untuk membantu meningkatkan kinerja kode saya sendiri (dan untuk belajar lebih banyak tentangnya). Saya datang ke sini mencari jawaban tentang kapan menggunakannya tetapi tampaknya ke mana pun saya pergi ada frasa seperti:
Gunakan inisialisasi malas untuk menunda pembuatan objek besar atau sumber daya intensif, atau pelaksanaan tugas sumber daya intensif, terutama ketika penciptaan atau eksekusi tersebut mungkin tidak terjadi selama masa program.
dari MSDN Lazy <T> Class
Saya sedikit bingung karena saya tidak yakin di mana harus menarik garis. Sebagai contoh, saya menganggap interpolasi linier sebagai perhitungan yang cukup cepat tetapi jika saya tidak perlu melakukannya, dapatkah inisialisasi malas membantu saya menghindari melakukannya dan apakah itu layak?
Pada akhirnya saya memutuskan untuk mencoba tes saya sendiri dan saya pikir saya akan membagikan hasilnya di sini. Sayangnya saya tidak benar-benar ahli dalam melakukan tes semacam ini dan jadi saya senang mendapatkan komentar yang menyarankan perbaikan.
Deskripsi
Untuk kasus saya, saya sangat tertarik untuk melihat apakah Properti Malas dapat membantu meningkatkan bagian dari kode saya yang melakukan banyak interpolasi (sebagian besar tidak digunakan) dan jadi saya telah membuat tes yang membandingkan 3 pendekatan.
Saya membuat kelas tes terpisah dengan 20 properti uji (sebut saja properti-t) untuk setiap pendekatan.
- GetInterp Class: Menjalankan interpolasi linier setiap kali properti-t didapat.
- Kelas InitInterp: Menginisialisasi sifat-t dengan menjalankan interpolasi linier untuk masing-masing di konstruktor. Dapatkan hanya mengembalikan dua kali lipat.
- Kelas InitLazy: Mengatur properti-t sebagai properti Malas sehingga interpolasi linier dijalankan sekali saat properti pertama kali didapat. Mendapat berikutnya hanya akan mengembalikan ganda yang sudah dihitung.
Hasil tes diukur dalam ms dan rata-rata 50 instansi atau 20 properti dapatkan. Setiap tes kemudian dijalankan 5 kali.
Hasil Tes 1: Instansiasi (rata-rata 50 Instansiasi)
Class 1 2 3 4 5 Avg %
------------------------------------------------------------------------
GetInterp 0.005668 0.005722 0.006704 0.006652 0.005572 0.0060636 6.72
InitInterp 0.08481 0.084908 0.099328 0.098626 0.083774 0.0902892 100.00
InitLazy 0.058436 0.05891 0.068046 0.068108 0.060648 0.0628296 69.59
Hasil Tes 2: First Get (rata-rata 20 properti mendapat)
Class 1 2 3 4 5 Avg %
------------------------------------------------------------------------
GetInterp 0.263 0.268725 0.31373 0.263745 0.279675 0.277775 54.38
InitInterp 0.16316 0.161845 0.18675 0.163535 0.173625 0.169783 33.24
InitLazy 0.46932 0.55299 0.54726 0.47878 0.505635 0.510797 100.00
Hasil Uji 3: Get Kedua (rata-rata 20 properti mendapat)
Class 1 2 3 4 5 Avg %
------------------------------------------------------------------------
GetInterp 0.08184 0.129325 0.112035 0.097575 0.098695 0.103894 85.30
InitInterp 0.102755 0.128865 0.111335 0.10137 0.106045 0.110074 90.37
InitLazy 0.19603 0.105715 0.107975 0.10034 0.098935 0.121799 100.00
Pengamatan
GetInterp
lebih cepat untuk instantiate seperti yang diharapkan karena tidak melakukan apa pun. InitLazy
lebih cepat untuk instantiate daripada InitInterp
menyarankan bahwa overhead dalam mengatur properti malas lebih cepat daripada perhitungan interpolasi linier saya. Namun, saya agak bingung di sini karena InitInterp
harus melakukan 20 interpolasi linier (untuk mengatur itu t-properti) tetapi hanya butuh 0,09 ms untuk instantiate (tes 1), dibandingkan dengan GetInterp
yang membutuhkan 0,28 ms untuk melakukan hanya satu interpolasi linier pertama kali (tes 2), dan 0,1 ms untuk melakukannya kedua kalinya (tes 3).
Dibutuhkan InitLazy
hampir 2 kali lebih lama daripada GetInterp
untuk mendapatkan properti pertama kali, sedangkan InitInterp
yang tercepat, karena dihuni properti selama instantiasi. (Setidaknya itu yang seharusnya dilakukan tetapi mengapa hasil instantiasi jauh lebih cepat daripada interpolasi linier tunggal? Kapan tepatnya melakukan interpolasi ini?)
Sayangnya sepertinya ada beberapa optimasi kode otomatis yang terjadi dalam pengujian saya. Perlu waktu GetInterp
yang sama untuk mendapatkan properti pertama kali seperti halnya yang kedua kalinya, tetapi itu menunjukkan lebih dari 2x lebih cepat. Sepertinya optimasi ini juga mempengaruhi kelas-kelas lain juga karena mereka semua mengambil jumlah waktu yang sama untuk pengujian 3. Namun, optimisasi semacam itu juga dapat terjadi dalam kode produksi saya sendiri yang mungkin juga menjadi pertimbangan penting.
Kesimpulan
Sementara beberapa hasil seperti yang diharapkan, ada juga beberapa hasil tak terduga yang sangat menarik mungkin karena optimisasi kode. Bahkan untuk kelas yang terlihat seperti mereka melakukan banyak pekerjaan di konstruktor, hasil instantiasi menunjukkan bahwa mereka mungkin masih sangat cepat untuk membuat, dibandingkan dengan mendapatkan properti ganda. Sementara para ahli di bidang ini mungkin dapat berkomentar dan menginvestigasi lebih menyeluruh, perasaan pribadi saya adalah bahwa saya perlu melakukan tes ini lagi tetapi pada kode produksi saya untuk memeriksa jenis optimisasi apa yang mungkin terjadi di sana juga. Namun, saya berharap itu InitInterp
mungkin jalan yang harus ditempuh.
get { if (foo == null) foo = new Foo(); return foo; }
. Dan ada zillions tempat yang memungkinkan untuk menggunakannya ...