Peki Regex Yavaş Kalırsa? Çözüm Çoooook Yakında :)

regexRegex’i seviyorum ve neredeyse bütün projelerimde mutlaka Regex kullanıyorum. Web yada masaüstü olması fark etmiyor. Çoğunlukla doğrulama ve parçalara ayırma işlemlerinde kullanıyorum. Ama bazı özel durumlar da Regex’in yavaşlığından şikayet etmeye başlıyorum. Homurdanıyorum ama yapacak birşey yok. Çünkü alternatifi yok. 

Mesela çok yoğun bir veri işleme sürecinde (ki burada sözü geçen yüzbinlerden başlıyor) Regex kullanıldığında belli oradan yavaşlama sıkıntıları ile karşılaşıyorum. Çoğu zaman bu yavaşlama benim için o kadar sorun yaratmasa da buna benzer bir kaç iş olduğu zaman performans sıkıntıları ile uğraşmak bayağı can sıkıcı oluyor. Böyle durumlarda eski usul ile çalışmak çok daha kolay ve hızlı oluyor. 

Peki bu eski usul ne? Tabiki de oradan oraya kadar kes, kontrol et, değilse farklı bir noktaya odaklan vs. vs. Ama bunlarıda biraz bile olsa otomatize edecek birşeye ihtiyaç duyduö. Bunun için kendime özel bir kaç satır kod yazarak belli bir oranda çözüme kavuştuğumu söyleyebilirim. Verdiğim Regex kodunu bana C# kodu olarak geri veriyor. Henüz beta denilebilecek bir seviyede değil ama zaman buldukça gerçek anlamda bir kütüphane oluşturmaya çalışıyorum.

C# kodunu vermeden önce test kodunu ve sonuçlarını vermek istiyorum. Testte 50.000.000 adet rastgele üretilmiş bir dosya yolu kontrol ediliyor. Önce .Net Framework içerisinde ki kütüphane kullanılıyor ikincisin de ise benim hazırladığım kod.

 

List<string> _names = new List<string>();
for (int i = 0; i < 50000000; i++)
    _names.Add(Path.GetRandomFileName());

var pattern = new _2Pattern();

System.Diagnostics.Stopwatch _watcher = new Stopwatch();
_watcher.Start();
for (int i = 0; i < _names.Count; i++)
    System.Text.RegularExpressions.Regex.Match(_names[i], @"[a-zA-Z0-9işğüçöÇÖŞİĞÜ\.\$ ]+");

_watcher.Stop();
Console.WriteLine("Regex : " + _watcher.Elapsed.ToString());
_watcher.Reset();

_watcher.Start();
for (int i = 0; i < _names.Count; i++)
    pattern.Execute(_names[i]);

_watcher.Stop();

Console.WriteLine("Pattern :" + _watcher.Elapsed.ToString());

_2Pattern sınıfı [a-zA-Z0-9işğüçöÇÖŞİĞÜ\.\$ ]+ Regex kodundan üretilmiş bir sınıftır. Yani aynı işi yapıyor.

Regex   : 00:00:57.8997673
Pattern : 00:00:12.8855927

Performans olarak biraz fark var :)
_2Pattern sınıfının kodu da aşağıda. _2Pattern sınıfı otomatik olarak üretilen bir sınıf.

public class _2Pattern
        {
            private static int[] chars = new int[] { 32, 36, 46, 48, 65, 97, 105, 199, 214, 220, 231, 246, 252, 286, 287, 304, 350, 351 };
            public bool Execute(string text)
            {
                for (int i = 0; i < text.Length; i++)
                {
                    if ((text[i] < 'a' || text[i] > 'z') && (text[i] < '0' || text[i] > '9') && (text[i] < 'A' || text[i] > 'Z') && IntArrayBinarySearch(chars, text[i]) < 0)
                        return false;
                }

                return true;
            }

            public static int IntArrayBinarySearch(int[] data, int item)
            {

                int min = 0;
                int N = data.Length;
                int max = N - 1;
                do
                {
                    int mid = (min + max) / 2;
                    if (item > data[mid])
                        min = mid + 1;
                    else
                        max = mid - 1;
                    if (data[mid] == item)
                        return mid;
                } while (min <= max);
                return -1;
            }
        }

Burada ki hızın en büyük nedeni aslında karakter bazlı tek tek arama ve binary search kullanıldı. .Net Framework‘ün kendi Binary Search metodu ne yazık ki çok generic bir yapıda olduğundan dolayı üstte ki kadar hızlı değildi ondan dolayı sınıfın içerisine dahil etmek zorunda kaldım.

Üstte ki Regex kodunun haricinde şu anda 

[a-z]{6, 12}
[a-z]{6,}
[a-z]{,12}
[a-z]{3}
[a-z]+
[a-z]*
[a-z]?

şeklinde ki Regex kodlarını da destekliyor. Ama daha üzerinde bir çok şey yapılması lazım ve bunun içinde bayağı bir zaman ayırmam gerekiyor. Şu an için o küçük kütüphaneyi yayınlamıyorum, biraz daha olgunlaşsın, daha kullanışlı hale gelsin o zaman zaten kodlarıyla birlikte yayınlayacağım.

Facebook Comments

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir