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
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
- Nesne başlatma maliyeti hakkında bakım ve ekstra performans artışı gerekmez. (not bir milisaniye burada kesirleri bahsediyoruz)
- 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.

Nasıl C89 modunda derlenmiş ve `C99` C...
Nasıl derlenmiş Java sınıfları yazılım...
Nasıl Derlenmiş Windows Dağıtmak Windo...
Nasıl mingw-gcc derlenmiş bir yürütüle...
Nasıl önceden derlenmiş varlıklar geli...