Saya memiliki buffer string sekitar 2000 karakter dan perlu memeriksa buffer jika berisi string tertentu.
Akan melakukan pemeriksaan di aplikasi web ASP.NET 2.0 untuk setiap permintaan web.
Apakah ada yang tahu jika metode String.Contains berkinerja lebih baik daripada metode String.IndexOf ?
// 2000 characters in s1, search token in s2
string s1 = "Many characters. The quick brown fox jumps over the lazy dog";
string s2 = "fox";
bool b;
b = s1.Contains(s2);
int i;
i = s1.IndexOf(s2);
Jawaban:
Contains
panggilanIndexOf
:Panggilan
CompareInfo.IndexOf
mana, yang pada akhirnya menggunakan implementasi CLR.Jika Anda ingin melihat bagaimana string dibandingkan di CLR, ini akan menunjukkan kepada Anda (cari CaseInsensitiveCompHelper ).
IndexOf(string)
tidak memiliki opsi danContains()
menggunakan perbandingan Ordinal (perbandingan byte-by-byte daripada mencoba melakukan perbandingan cerdas, misalnya, e dengan é).Jadi
IndexOf
akan sedikit lebih cepat (dalam teori) karenaIndexOf
langsung ke pencarian string menggunakan FindNLSString dari kernel32.dll (kekuatan reflektor!).Diperbarui untuk .NET 4.0 - IndexOf tidak lagi menggunakan Perbandingan Ordinal sehingga Mengandung bisa lebih cepat. Lihat komentar di bawah.
sumber
IndexOf()
memang menggunakanStringComparison.CurrentCulture
danContains()
menggunakanStringComparison.Ordinal
yang akan lebih cepat. Tetapi sebenarnya perbedaan kecepatan yang kita bicarakan adalah menit - intinya adalah satu memanggil yang lain, dan Berisi lebih mudah dibaca jika Anda tidak memerlukan indeks. Dengan kata lain jangan khawatir tentang itu.Mungkin, itu tidak masalah sama sekali. Baca posting ini di Coding Horror;): http://www.codinghorror.com/blog/archives/001218.html
sumber
Berisi (s2) berkali-kali (di komputer saya 10 kali) lebih cepat daripada IndexOf (s2) karena Berisi menggunakan StringComparison.Ordinal yang lebih cepat daripada pencarian sensitif budaya yang dilakukan IndexOf secara default (tetapi itu dapat berubah di .net 4.0 http: //davesbox.com/archive/2008/11/12/breaking-changes-to-the-string-class.aspx ).
Berisi memiliki kinerja yang persis sama dengan IndexOf (s2, StringComparison.Ordinal)> = 0 dalam pengujian saya tetapi lebih pendek dan membuat niat Anda jelas.
sumber
Saya menjalankan kasus nyata (berlawanan dengan tolok ukur sintetis)
melawan
Ini adalah bagian penting dari sistem saya dan dijalankan 131.953 kali (terima kasih DotTrace).
Betapapun mengejutkannya , hasilnya berlawanan dengan yang diharapkan
: - /
kerangka kerja bersih 4.0 (diperbarui untuk 13-02-2012)
sumber
INT
jauh lebih besar dariBOOL
, danIndexOf>=0
menyebabkan satu langkah lagiDengan menggunakan Reflector, Anda dapat melihat, bahwa Contains diimplementasikan menggunakan IndexOf. Berikut implementasinya.
Jadi Contains sepertinya sedikit lebih lambat daripada memanggil IndexOf secara langsung, tapi saya ragu itu akan memiliki signifikansi untuk kinerja sebenarnya.
sumber
Jika Anda benar-benar ingin mengoptimalkan mikro kode Anda, pendekatan terbaik Anda selalu benchmarking.
Kerangka .net memiliki implementasi stopwatch yang sangat baik - System.Diagnostics.Stopwatch
sumber
Dari sedikit pembacaan, tampak bahwa di bawah tenda metode String.Contains hanya memanggil String.IndexOf. Perbedaannya adalah String.Contains mengembalikan boolean sementara String.IndexOf mengembalikan integer dengan (-1) yang menyatakan bahwa substring tidak ditemukan.
Saya akan menyarankan menulis tes kecil dengan 100.000 atau lebih iterasi dan lihat sendiri. Jika saya harus menebak, saya akan mengatakan bahwa IndexOf mungkin sedikit lebih cepat tetapi seperti yang saya katakan itu hanya tebakan.
Jeff Atwood memiliki artikel bagus tentang string di blognya . Ini lebih tentang penggabungan tetapi mungkin tetap membantu.
sumber
Sama seperti pembaruan untuk ini, saya telah melakukan beberapa pengujian dan memberikan string input Anda cukup besar maka Regex paralel adalah metode C # tercepat yang saya temukan (asalkan Anda memiliki lebih dari satu inti yang saya bayangkan)
Mendapatkan jumlah total pertandingan misalnya -
Semoga ini membantu!
sumber
Gunakan pustaka patokan, seperti upaya terbaru dari Jon Skeet untuk mengukurnya.
Caveat Emptor
Seperti semua pertanyaan kinerja (mikro), ini tergantung pada versi perangkat lunak yang Anda gunakan, detail data yang diinspeksi, dan kode seputar panggilan.
Seperti semua pertanyaan kinerja (mikro), langkah pertama yang harus dilakukan adalah mendapatkan versi berjalan yang mudah dipelihara. Kemudian benchmarking, profiling, dan tuning dapat diterapkan ke bottleneck yang diukur, bukan menebak-nebak.
sumber
Bagi siapa pun yang masih membaca ini, indexOf () mungkin akan bekerja lebih baik di sebagian besar sistem perusahaan, karena berisi () tidak kompatibel dengan IE!
sumber