SearchValues<T> akhirnya menunjukkan kelebihan yang ketara dalam .NET 10 apabila mengimbas penimbal (buffer) besar untuk pembatas (delimiter) yang jarang, dengan SearchValues selesai dalam 3.3 ms berbanding larian IndexOfAny selama 5.6 ms pada muatan (payload) 32 MB.
Mengapa SearchValues diperkenalkan
.NET 8 memperkenalkan SearchValues<T> untuk mengira awal (pre-compute) satu set aksara (atau bait) dan membolehkan runtime memilih algoritma pengimbasan terpantas untuk set tersebut. Bina objek itu sekali, kemudian gunakannya semula setiap kali anda perlu mencari mana-mana nilai dalam satu span. Runtime mungkin menggunakan arahan vektor (vectorized instructions), gelung tanpa cawangan (branch-free loops), atau helah tahap rendah lain yang tidak dapat ditandingi oleh alternatif yang ditulis secara manual tanpa usaha yang besar.
Penanda aras yang penting
Ujian yang mencetuskan perbincangan ini menggunakan penimbal 32 MB yang mengandungi lima aksara pembatas. Tiga pendekatan telah diukur masanya pada .NET 10:
- IndexOfAny(char[]) – 10.2 ms
- Gelung foreach manual pada span – 19.4 ms
- SearchValues
– 9.7 ms
SearchValues menewaskan IndexOfAny terbina dalam dengan hanya separuh milisaat. Keputusannya bukanlah dakwaan dramatik "lima kali lebih pantas" yang tular di forum; .NET moden sudah pun mengoptimumkan IndexOfAny untuk set kecil, sekali gus merapatkan jurang tersebut.
Apabila pembatas adalah jarang—muncul sekali setiap 40 KB dan bukannya setiap 60 bait—gambaran berubah:
- IndexOfAny(char[]) – 5.6 ms
- SearchValues
– 3.3 ms
Kini SearchValues adalah 1.7 × lebih pantas kerana enjin tersebut memecut melalui siri data yang tidak sepadan yang panjang dengan langkah vektor, manakala IndexOfAny beralih kepada laluan yang kurang agresif.
Kos tersembunyi
SearchValues tidak percuma. Membina objek tersebut memperuntukkan memori dan membina jadual carian dalaman. Jika anda melakukan instansiasi (instantiate) pada setiap panggilan kaedah, beban kerja (overhead) tersebut akan mengatasi sebarang kelebihan masa larian. Penanda aras yang memanggil rutin pengimbasan sebanyak satu juta kali pada baris pendek menunjukkan:
- SearchValues Statik (diguna semula) – 25.1 ms jumlah keseluruhan
- SearchValues Setiap-panggilan – 70.2 ms jumlah keseluruhan
Mencipta objek bagi setiap panggilan menjadikan keseluruhan operasi tiga kali lebih lambat berbanding tidak menggunakan SearchValues langsung. Simpan instans tersebut dalam medan static readonly atau gunakan semula merentasi panggilan.
Bila perlu menggunakan SearchValues
- Input besar, padanan sedikit – Laluan vektor menyerlah apabila pengimbas boleh melangkau kawasan yang panjang tanpa menemui pembatas.
- Pengimbasan berulang dengan set yang sama – Jika aksara yang sama dicari berkali-kali, persediaan sekali sahaja itu akan memberikan hasil yang berbaloi.
Bila perlu kekal dengan IndexOfAny
- String pendek atau banyak padanan – Kos persediaan tambahan mengatasi peningkatan kelajuan yang kecil.
- Kod yang sudah menggunakan IndexOfAny – Implementasi .NET moden sudah pun ditala dengan sangat baik untuk set aksara kecil, jadi menukar kepada
SearchValuesmungkin tidak memberikan perbezaan yang ketara.
Perangkap biasa
- Menanam pembinaan objek dalam gelung panas (hot loops) – Mengakibatkan kelembapan tiga kali ganda seperti yang ditunjukkan di atas.
- Cuba untuk "mengatasi" runtime dengan gelung manual – Versi
foreachmanual adalah dua kali lebih lambat daripada kedua-dua kaedah terbina dalam, mengesahkan bahawa perpustakaan .NET sukar ditandingi tanpa pengetahuan mendalam tentang arahan SIMD. - Menganggap peningkatan kelajuan adalah universal – Kemenangan separuh milisaat pada data padat membuktikan bahawa
SearchValuesbukanlah kod helah universal; manfaatnya bergantung kepada data.
Kesimpulan
SearchValues<T> memberikan kelebihan yang jelas hanya apabila anda mengimbas penimbal besar untuk aksara yang jarang muncul dan mampu menanggung kos pembinaan sekali sahaja. Bagi kebanyakan senario carian string harian—input pendek, padanan kerap, atau kod yang sudah bergantung pada IndexOfAny—kaedah terbina dalam kekal sebagai pilihan yang lebih mudah dan pantas. Gunakan SearchValues secara terpilih, simpan (cache) instans tersebut, dan anda akan mengelakkan penalti tersembunyi sambil meraih kemenangan prestasi yang sebenar.
Kod sumber dan set ujian penuh: https://dev.to/ssukhpinder/when-searchvalues-actually-pays-off-310l
