Ne tür bir uygulama geliştiriyor olursak olalım (Web, Mobile, Cloud, Game, Desktop, etc) string tipi üzerinde karşılaştırma mutlaka yaparız.
Bu makalede, string değişkenler üzerinde yapabileceğimiz karşılaştırma methodlarını performans odaklı olarak inceleyeceğiz.
Ben aşağıdaki 4 yöntemi karşılaştırmaya karar verdim, eğer sizin aklınıza başka karşılaştırma yöntemleri gelirse, aşağıdaki Yorumlar alanına veya Issues altına bir yorum bırakabilirsiniz ;)
Öncelikle test ortamımızı oluşturalım, bunun için TestScenarios ve Program isimli birer class oluşturuyoruz.
Program.cs dosyasında yeralan Program class‘ında sadece TestScenarios class‘ından yeni bir instance oluşturup, InvokeTest() methodunu çağırıyoruz;
TestScenarios class‘ı içerisinde, üzerinde testleri geçekleştireceğimiz, string bir değişkene ihtiyacımız var;
Ben, kendi bilgisayarımda, karşılaştırma operasyonunu 10 Milyon (10_000_000) defa yapıp, toplam harcanan süreyi ölçtüm;
Karşılaştırma operasyonunu gerçekleştirip, sonucu ekrana yazdırabilmek için TestAndPrint() isimli bir method geliştirdim;
Bu method içerisinde, öncelikle, Stopwatch tipinde bir değişken oluşturuyorum.
GarbageCollector tarafından testin etkilenmemesi için, GC sınıfının Collect() methodunu Generation 2 için çalıştırıyorum.
Sonra da, WaitForFullGCComplete() methodu ile, eğer yürüyen bir Collect() operasyonu varsa, tamamlanmasını bekliyorum.
Stopwatch değişkenini Restart() edip, sıfırlıyor, Action tipinde aldığım Test() parametresini çağırıyor, geçen toplam süreyi milisaniye cinsinden ekrana yazıyorum.
Şimdi, tek tek, String.IndexOf(), String.Contains(), Regex.IsMatch() ve Regex.IsMatch(Compiled) test senaryolarını yazalım;
String.IndexOf() testi için;
String.Contains() testi için;
Regex.IsMatch() testi için;
Regex.IsMatch(Compiled) testi için;
Şimdi, TestScenarios class içerisine InvokeTest() methodu yazıyoruz;
Her testi 2 kere çalıştırıyoruz, biri karşılaştırma sonucu başarılı olacak şekilde, biri başarılı olmayacak şekilde.
Gelelim, en önemli kısma, karşılaştırma sonuçları :)
Sonuçlara baktığım zaman aşağıdaki noktalar dikkatimi çekti;
Microsoft‘un Github‘da yayınladığı ReferenceSource repository’sinde String classının Contains() methodu aşağıdaki şekilde yazılmış;
Aslında Contains() methodu, içeride IndexOf() methodunu çağırıyor.
Peki, neden bizim testlerimizde Contains() ve IndexOf() farklı sonuçlar üretti?
Çünkü, Contains() methodu içinden IndexOf() methodu, StringComparison.Ordinal
parametresi ile çağırılıyor.
Eğer kendi uygulamalarımızda IndexOf() methodunu çağıracaksak, StringComparison.Ordinal
parametresini kullanmamız performans artışı sağlayacaktır.
Daha kolayı, Contains() methodunu kullanmak :)
Senior Software Engineer, @Microsoft
Ada ve Ege'nin babası ;)
Makale Adedi: 484