SORU
4 ŞUBAT 2009, ÇARŞAMBA


Nasıl RegexOptions.Derlenmiş iş?

Bir düzenli ifade işaretlediğinizde perde arkasında neler derlenecek nedir? Nasıl önbelleğe alınan bu normal bir ifade farklıdır/farkı nedir?

Bu bilgileri kullanarak, nasıl hesaplama maliyet performansı artırmak için karşılaştırıldığında önemsiz olduğunu ayırt edersiniz?

CEVAP
9 EKİM 2011, Pazar


RegexOptions.Compiled düzenli ifade motoru IL içine düzenli ifade ifade hafif kod üretimi kullanarak (LCG) derlemek için yönlendirir. Bu derleme nesne inşaat sırasında olurağıryavaşlar. Sırayla eşleşen düzenli ifade kullanarak daha hızlıdır.

Eğer bu bayrak belirtirseniz değil, düzenli ifade olarak kabul edilir "". yorumlanır

Bu örnek alın:

public static void TimeAction(string description, int times, Action func)
{
    // warmup
    func();

    var watch = new Stopwatch();
    watch.Start();
    for (int i = 0; i < times; i  )
    {
        func();
    }
    watch.Stop();
    Console.Write(description);
    Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
}

static void Main(string[] args)
{
    var simple = "^\\d $";
    var medium = @"^((to|from)\W)?(?<url>http://[\w\.:] )/questions/(?<questionId>\d )(/(\w|-)*)?(/(?<answerId>\d ))?";
    var complex = @"^(([^<>()[\]\\.,;:\s@""] "
        @"(\.[^<>()[\]\\.,;:\s@""] )*)|("". ""))@"
        @"((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
        @"\.[0-9]{1,3}\])|(([a-zA-Z\-0-9] \.) "
        @"[a-zA-Z]{2,}))$";


    string[] numbers = new string[] {"1","two", "8378373", "38737", "3873783z"};
    string[] emails = new string[] { "sam@sam.com", "sss@s", "sjg@ddd.com.au.au", "onelongemail@oneverylongemail.com" };

    foreach (var item in new[] {
        new {Pattern = simple, Matches = numbers, Name = "Simple number match"},
        new {Pattern = medium, Matches = emails, Name = "Simple email match"},
        new {Pattern = complex, Matches = emails, Name = "Complex email match"}
    })
    {
        int i = 0;
        Regex regex;

        TimeAction(item.Name   " interpreted uncached single match (x1000)", 1000, () =>
        {
            regex = new Regex(item.Pattern);
            regex.Match(item.Matches[i   % item.Matches.Length]);
        });

        i = 0;
        TimeAction(item.Name   " compiled uncached single match (x1000)", 1000, () =>
        {
            regex = new Regex(item.Pattern, RegexOptions.Compiled);
            regex.Match(item.Matches[i   % item.Matches.Length]);
        });

        regex = new Regex(item.Pattern);
        i = 0;
        TimeAction(item.Name   " prepared interpreted match (x1000000)", 1000000, () =>
        {
            regex.Match(item.Matches[i   % item.Matches.Length]);
        });

        regex = new Regex(item.Pattern, RegexOptions.Compiled);
        i = 0;
        TimeAction(item.Name   " prepared compiled match (x1000000)", 1000000, () =>
        {
            regex.Match(item.Matches[i   % item.Matches.Length]);
        });

    }
}

3 farklı düzenli ifadeler üzerinde 4 testleri gerçekleştirir. İlk testleritekbir kere off maçı (vs olmayan derlenmiş derlenmiş). İkinci tekrar aynı düzenli ifade maçları yeniden test eder.

Benim makinede sonuçları (release, hata ayıklayıcı ekli derlenmiş)

1000 tek maçlar (Düzenli ifade oluşturmak, Maç ve imha)

Type        | Platform | Trivial Number | Simple Email Check | Ext Email Check
------------------------------------------------------------------------------
Interpreted | x32      |    4 ms        |    26 ms           |    31 ms
Interpreted | x64      |    5 ms        |    29 ms           |    35 ms
Compiled    | x32      |  913 ms        |  3775 ms           |  4487 ms
Compiled    | x64      | 3300 ms        | 21985 ms           | 22793 ms

1,000,000 maçlarında Düzenli yeniden nesne

Type        | Platform | Trivial Number | Simple Email Check | Ext Email Check
------------------------------------------------------------------------------
Interpreted | x32      |  422 ms        |   461 ms           |  2122 ms
Interpreted | x64      |  436 ms        |   463 ms           |  2167 ms
Compiled    | x32      |  279 ms        |   166 ms           |  1268 ms
Compiled    | x64      |  281 ms        |   176 ms           |  1180 ms

Bu sonuçlar derlenmiş normal ifadeler için olabilir60%daha hızlı Regex nesneyi yeniden durumlar için.Ancakbazı durumlarda söz konusu olabilirBüyüklükte 3 emiryavaş inşa etmek.

O da bunu gösterirx 64 sürümü.NET olabilir5-6 kat daha yavaşdüzenli ifadelerin derlenmesi gelince.


Öneri olacaktırderlenmiş sürümü kullanındurumlarda da

  1. Nesne başlatma maliyeti hakkında bakım ve ekstra performans artışı gerekmez. (not bir milisaniye burada kesirleri bahsediyoruz)
  2. Başlatma maliyet hakkında biraz umurunda, ama Düzenli bunu telafi edecek bir çok kez nesne uygulama yaşam döngüsü sırasında yeniden.

Çalışır İngiliz anahtarı, Düzenli önbelleği

Düzenli ifade motoru Regex Sınıf statik yöntemler kullanılarak test edildi son 15 düzenli ifadeler taşıyan bir LRU önbellek içerir.

Örneğin:*, *9 Regex.Replace vb tüm kullanım Düzenli önbelleği.

Önbellek boyutu Regex.CacheSize AYAR artar. Uygulamalar yaşam döngüsü sırasında herhangi bir zaman boyutu değişiklikleri kabul eder.

Yeni düzenli ifadeler sadece önbelleğe alınırstatik yardımcıları tarafındanDüzenli sınıfı. Cache işaretli nesneleri (yeniden ve bombeli) oluşturmak, ancak, düzenli ifade oluşturmakönbellek eklenmiş.

Bu önbellekönemsizLRU önbellek, çift bağlantılı basit bir liste ile kodlandı. Eğer 5000 ve statik yardımcıları 5000 farklı çağrıları kullanmak için bunu artırmak için ne varsa, her düzenli ifade inşaatı 5000 girişleri daha önce önbelleğe alınmış olup olmadığını görmek için tarar. Bir yokturkilitonay paralellik azaltmak ve iş parçacığı engelleme tanıtmak, böylece yaklaşık kontrol edin.

Bu sayı bazı durumlarda ama bunu artırmak için başka seçeneğiniz olsa da oldukça düşük bu gibi durumlarda kendinizi korumak için ayarlanır.

Benimgüçlü bir önerioluraslastatik bir yardımcı için RegexOptions.Compiled bir seçenek sunar.

Örneğin:

\\ WARNING: bad code
Regex.IsMatch(@"\\d ", "10000", RegexOptions.Compiled)

Sebebi ağır bir tetikleyecek LRU önbellek üzerinde bir bayan riske vardırsüper pahalıderleme. Ayrıca, yaşaman kütüphaneler ne yaptığını bilmiyorsun, ya da kontrol tahmin etmek için çok az yeteneği varmümkün olan en iyiönbellek boyutu.

Ayrıca bakınız: BCL team blog


Notbu konu ile ilgili .NET 2.0 ve .NET 4.0. Bu revize edilmesine neden olabilir 4.5 beklenen bazı değişiklikler var.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Evan Coury

    Evan Coury

    29 NİSAN 2007
  • My name is Festis and I'm free

    My name is F

    2 EKİM 2011
  • ICON

    ICON

    19 EKİM 2011