Refleksi: Apakah menggunakan refleksi masih “buruk” atau “lambat”? Apa yang telah berubah dengan refleksi sejak 2002?

21

Saya perhatikan ketika berhadapan dengan Ekspresi atau Pohon Ekspresi. Saya banyak menggunakan refleksi untuk menetapkan dan mendapatkan nilai dalam properti dan apa pun yang Anda miliki. Terlintas dalam benak saya bahwa penggunaan refleksi tampaknya semakin umum. Hal-hal seperti DataAnotations untuk validasi, Atribut ORM berat, dll. Pernahkah saya bertanya-tanya: Apa yang telah berubah sejak hari-hari yang lalu ketika saya dulu diberitahu untuk menghindari refleksi jika mungkin?

Jadi apa, jika ada yang berubah? Apakah hanya kecepatan mesin? Apakah ada perubahan pada kerangka kerja untuk mempercepat refleksi?

Atau tidak ada yang benar-benar berubah? Apakah masih "buruk" atau "lambat" untuk menggunakan refleksi?

daging
sumber
2
Refleksi akan selalu lebih lambat daripada panggilan langsung, karena Anda harus melakukan beberapa langkah untuk menemukan dan memverifikasi bahwa apa yang Anda panggil ada.
Michael K
Itu selalu buruk .... Tentu saja kadang-kadang Anda tidak punya pilihan, terserah kepada programmer untuk mengetahui kapan waktu itu, dan menghindarinya sebaliknya.
Ramhound
Melakukan Refleksi dengan gettype untuk menarik satu item dalam enum masih lebih dari 30 kali lebih cepat daripada melempar pengecualian dengan Enum.Parse (). Jadi refleksi terkadang menang.
Brain2000

Jawaban:

16

Refleksi tidak buruk, juga tidak lambat. Ini hanyalah alat. Seperti semua alat, itu sangat berharga untuk skenario tertentu, tidak begitu berharga untuk orang lain.

Jika kinerja benar-benar masalah, Anda selalu dapat menggunakan perpustakaan seperti FasterFlect .

Bacaan Lebih Lanjut
Jika refleksi tidak efisien, kapan itu paling tepat?

Robert Harvey
sumber
Atau dynamic- tampaknya urutan besarnya lebih cepat daripada refleksi.
Oded
1
Kinerja sama sekali bukan masalah. Saya hanya ingat dengan jelas orang-orang yang menghindari refleksi pada tahun 2002 seolah itu adalah wabah. Saya bertanya-tanya apa yang berubah sejak saat itu.
blesh
3
@blesh: Tidak ada. Orang-orang lebih mengenalnya sekarang, dan tidak terlalu takut padanya.
Robert Harvey
5
Saya bisa menjadi "turun dari halaman" di sini dan mengatakan bahwa Lisp memiliki ini jauh sebelum OOP ada ...
Michael K
Cukup adil. Saya hanya bertanya-tanya apakah itu peningkatan kecepatan dalam mesin dalam sepuluh tahun terakhir yang telah membuat perbedaan atau apakah sebenarnya ada perubahan yang dilakukan pada System.Refleksi yang telah meningkatkan kinerja.
blesh
17

Alasan orang waspada menggunakan refleksi yang tidak perlu bukanlah kinerja: ya, ada beberapa overhead untuk menggunakan refleksi, tetapi seringkali, menyelesaikan masalah tanpa itu memerlukan pendekatan yang berbeda dengan kompleksitas yang sebanding, dan bahkan jika tidak, biaya overhead adalah jarang signifikan (terutama untuk pengembangan tingkat aplikasi).

Menggunakan refleksi, beberapa asumsi penting yang biasanya dapat dibuat tentang kode sumber rusak, dan alat-alat seperti "Temukan Semua Referensi" berhenti bekerja dengan andal. Refleksi pada dasarnya juga menghapus sebagian besar jenis keselamatan yang diberlakukan oleh kompiler, katakanlah, C #, dan sebagian besar kesalahan pemrograman yang biasanya ditemui oleh sistem tipe dan diterjemahkan ke dalam kesalahan kompiler, sekarang menjadi kesalahan runtime yang terbaik atau bug yang sangat tidak jelas yang terburuk.

Jadi mengapa orang menggunakan refleksi itu? Sederhananya, karena meskipun masalah yang dijelaskan di atas, itu adalah alat yang sangat berharga. Dengan refleksi, beberapa manfaat pemrograman dinamis dapat dimiliki dalam bahasa statis yang diketik dengan ketat seperti C #, dan bahasa pemrograman dinamis telah menunjukkan kemampuannya baru-baru ini, terutama dalam bidang pemrograman web - PHP, Javascript, dan Python yang cukup menonjol , semua menggunakan pengetikan dinamis, dan telah terbukti cocok untuk pemrograman web. Tetapi karena bahasanya masih C #, Anda dapat memilih untuk menyimpan sebagian besar aplikasi Anda dalam idiom OOP yang diketik dengan ketat, dan menulis bagian kecil di mana perilaku dinamis benar-benar membuat perbedaan dengan refleksi.

Contoh khas adalah ketika Anda perlu mengekspos metode sebagai panggilan layanan web (menggunakan protokol yang belum dibangun ke dalam .NET). Pendekatan OOP yang diketik secara ketat memang berhasil, tetapi terlalu ketat dan kaku. Tetapi jika Anda menggunakan refleksi untuk memetakan panggilan ke metode dan pasangan kunci / nilai untuk argumen, Anda bisa menulis pipa ledeng untuk layanan web seperti itu sekali dan kemudian menggunakannya pada kelas yang Anda suka.

tammmer
sumber
13

Refleksi masih jauh lebih lambat daripada panggilan langsung. Dua hal telah berubah:

  • Runtimes telah mengoptimalkan mekanisme refleksi sehingga perbedaannya menjadi lebih kecil
  • CPU menjadi lebih cepat sehingga inefisiensi kecil lebih mudah ditoleransi

Bersama-sama, kedua faktor ini telah membawa biaya refleksi ke titik di mana Anda dapat menggunakannya secara rutin (jika perlu dari POV pemeliharaan) dan menunggu profiler memberi tahu Anda apakah itu sebenarnya hambatan (dan cukup yakin bahwa sebagian besar waktu tidak).

Michael Borgwardt
sumber
4
sayangnya, CPU menjadi lebih lambat - biasanya pada perangkat seluler, dan server tempat orang berusaha menekan efisiensi sebanyak mungkin dari server mereka karena biaya untuk menjalankannya.
gbjbaanb
@ gbjbaanb: Saya akan memberi Anda perangkat seluler, tetapi di server, membeli lebih banyak perangkat keras daripada mengoptimalkan kode adalah pilihan yang diterima dan rasional di sebagian besar kasus, karena biaya untuk membeli dan menjalankan server jauh lebih rendah daripada biaya optimalisasi kode.
Michael Borgwardt
2
Dalam beberapa situasi, biaya server secara dramatis lebih besar daripada biaya pengembangan. Dalam gaya skala besar. Meskipun server adalah buff, kinerja dapat menjadi lebih penting daripada pada mesin klien. Ini adalah skenario kasus per kasus.
Lord Tydus
1
@ Lord Tydus: tentu, tetapi kasus yang Anda gambarkan adalah pengecualian yang jarang.
Michael Borgwardt