Dlaczego wyrażenia regularne skompilowane w C # są szybsze niż równoważne metody łańcuchowe?

Za każdym razem, gdy muszę wykonywać proste operacje przechowywania lub wymiany na łańcuchach, gdzie szukany termin jest wartością stałą, stwierdzam, że jeśli biorę moje przykładowe dane wejściowe i wykonuję na nich jakieś profilowanie, użycie skompilowanego wyrażenia regularnego to prawie * zawsze szybciej niż przy użyciu równoważnej metody z klasy String.

Próbowałem porównać różne metody (hs jest „stóg siana” do przeszukania,ndl jest „igłą” do wyszukania,repl jest wartością zastępczą.regex jest zawsze tworzony za pomocąRegexOptions.Compiled opcja ):

hs.Replace( ndl, repl ) vsregex.Replace( hs, repl )hs.Contains( ndl ) vsregex.IsMatch( hs )

Znalazłem sporo dyskusji na ten tematktóry z dwóch technik są szybsze (1, 2, 3i mnóstwo innych), ale te dyskusje zawsze wydają się skupiać na:

Użyj wersji łańcuchowej dla prostych operacji i wyrażenia regularnego dla złożonych operacji (które, z surowej perspektywy wydajności, nawet nie wydają się być koniecznie dobrym pomysłem), lubUruchom test i porównaj dwa (i dla równoważnych testów wersja regex wydaje się zawsze działać lepiej).

Nie rozumiem, jak to może być w przypadku: w jaki sposób silnik regex porównuje dwa ciągi dla dopasowań podciągów szybciej niż odpowiednia wersja ciągu? Wydaje się, że jest to prawdą w przypadku bardzo małych lub bardzo dużych przestrzeni wyszukiwania lub wyszukiwanych haseł, które są małe lub duże, lub czy wyszukiwane hasło występuje wcześnie lub późno w przestrzeni wyszukiwania.

Więc,czemu czy wyrażenia regularne są szybsze?

* W rzeczywistościtylko przypadku udało mi się pokazać, że wersja łańcucha jest szybsza niż skompilowane wyrażenie regularne podczas wyszukiwania pustego łańcucha! Każdy inny przypadek, od pojedynczych ciągów znaków do bardzo długich ciągów, jest przetwarzany szybciej przez skompilowane wyrażenie regularne niż równoważna metoda łańcuchowa.

Aktualizacja: Dodano klauzulę wyjaśniającą, że szukam przypadków, w których wyszukiwane hasło jest znane w czasie kompilacji. W przypadku operacji dynamicznych lub jednorazowych narzut kompilowania wyrażenia regularnego będzie miał tendencję do pochylania wyników na korzyść metod łańcuchowych.

questionAnswers(3)

yourAnswerToTheQuestion