정규식 방법을 분리하고 벤치마크를 사용하여 비교를 확인할 수 있다면 꼭 필요한 경우 정규식 속도를 높일 수 있습니다.
생산 압력 하에서 정규 표현식 속도를 높이는 방법(How to Speed Regular Expressions under Production Pressure) 에서 번역됨 , 저자 David Eastman.
여러 기사 에서 정규 표현식의 장점을 언급했지만 속도가 느려질 수 있다는 점은 언급한 적이 없기 때문에 정규 표현식 사용의 장점을 지적할 때 약간 죄책감을 느낍니다 .
많은 응용 사례에서 정규식의 속도는 문제가 되지 않습니다. 단지 양식을 통해 몇 가지 질문을 캡처할 뿐입니다. 하지만 속도가 중요할 때 당신은 갑자기 타임 킬러를 찾는 형사가 됩니다. 이를 통해 어떤 코드가 비효율적인지 파악해야 하지만, 생산 압박 속에서 속도를 높이는 것은 어려운 일입니다.
C# 예제를 사용하겠지만 중요한 점은 일반적으로 사용하는 언어에 관계없이 정규식을 사용하는 방법에 주의를 기울여야 하며 정규식 컴파일과 같은 옵션이 도움이 될 수 있다는 것입니다.
실행 속도를 비교할 때 유효한 비교를 위해 일종의 벤치마크 도구를 사용해야 합니다. 다행히 BenchmarkDotNet이 이미 존재합니다. 이는 우리에게 필요한 콘솔 애플리케이션에서 작동합니다.
솔루션 없이도 프로젝트를 생성하고 표시하는 데 더 나은 Visual Studio Code를 계속 사용할 것입니다. 작업 속도를 높이기 위해 템플릿을 사용하겠습니다.
Warp를 열고 먼저 다음 단계를 실행했습니다.
이는 적절한 프로젝트 프레임워크를 설정하기 위해 사용 가능한 벤치마크 템플릿을 사용하여 우리 이름으로 명명된 프로젝트를 설정하기 만 하면 됩니다. BenchmarkRegex
다음 디렉토리에 생성된 파일을 볼 수 있습니다.
code .
그런 다음 명령을 사용하여 VS Code를 시작할 수 있습니다 .
하지만 먼저 이전 기사에서 실행했던 몇 가지 정규식 작업을 고려해 보겠습니다. 우리는 영어에서 "c 뒤를 제외하고 e 앞의 i"가 종종 깨지는 것을 보여주기 위해 교대 및 탐색을 사용하는 까다로운 패턴을 사용했습니다.
위의 패턴은 "c" 없이 "cie" 또는 "ei"를 검색하여 파괴적인 예를 찾습니다. 둘러보기는 구현에 따라 다르게 동작할 수 있으므로 주의해서 사용해야 하는 정규식의 함수 중 하나입니다. 이 경우 부정 예측(?<!c)을 사용하여 "ei" 앞에 "c"가 오지 않는지 확인하지만 해당 "c"를 사용하지 않습니다. 자세한 내용은 기사를 읽어보세요.
이 예제 텍스트와 패턴을 새 템플릿 파일 _Benchmark.cs_에 직접 넣을 수 있습니다.
using System;
using System.Text.RegularExpressions;
using BenchmarkDotNet;
using BenchmarkDotNet.Attributes;
namespace BenchmarkRegex
{
public class Benchmarks
{
private const string Pattern = @"(cie|(?<!c)ei)";
private const string GoodText = "Good: ceiling, receipt, deceive, chief, field, believe.";
private const string BadText = "Bad: species, science, sufficient, seize, vein, weird.";
static bool printMeOnce = false;
[Benchmark]
public void Scenario1()
{
// Implement your benchmark here var
f = Regex.IsMatch(GoodText + BadText, Pattern);
if (!printMeOnce) foreach (Match match in Regex.Matches(GoodText+BadText, Pattern, RegexOptions.None))
Console.WriteLine("Found '{0}' at position {1}", match.Value, match.Index);
printMeOnce = true;
}
}
}
먼저 일치 항목이 유효한지, 6가지 사례를 포착했는지 확인합니다.
릴리스 모드에서만 콘솔 애플리케이션을 벤치마크할 수 있습니다. 이는 Warp 명령줄에서 실행할 수 있으므로 괜찮습니다 dotnet run -C Release
. 곧 로그에서 6건의 사례가 포착되었다는 확인을 받았습니다.
마지막으로 벤치마크를 얻습니다.
알았어, 좋아. 물론 이제 정규식 속도를 높이는 주제로 돌아가야 합니다. 따라서 가장 확실한 첫 번째 접근 방식은 스키마를 정적 으로 만드는 것입니다 . 이제 패턴이 작동한다는 것을 확인했으므로 출력을 버릴 수 있습니다. 결국 이로 인해 벤치마크가 매우 느려지게 됩니다!
..
private const string Pattern = @"(cie|(?<!c)ei)";
private static readonly string StaticPattern = @"(cie|(?<!c)ei)";
..
[Benchmark] public void Scenario1()
{
// Implement your benchmark here
Regex.Matches(GoodText+BadText, Pattern, RegexOptions.None);
}
[Benchmark] public void Scenario2()
{
// Implement your benchmark here
Regex.Matches(GoodText+BadText, StaticPattern, RegexOptions.None);
}
..
따라서 대략적으로 두 번째 시나리오가 더 빠를 것으로 예상됩니다. 실제로는 다음과 같습니다.
(예, 인쇄하지 않으면 나노초 범위에 있습니다.)
이제 벤치마크 테스트가 완료되었으므로 컴파일 옵션을 테스트할 수 있습니다.
private const string Pattern = @"(cie|(?<!c)ei)";
private static readonly string StaticPattern = @"(cie|(?<!c)ei)";
private static readonly Regex CompiledRegex = new(Pattern, RegexOptions.Compiled);
..
[Benchmark] public void Scenario3()
{
CompiledRegex.Matches(GoodText+BadText);
}
..
그렇다면 이 벤치마크는 어떻게 쌓일까요?
글쎄요, 절반 정도요. 그러나 이는 명확한 결론은 아니다. 당신이 알아야 할 많은 일들이 그 안팎에서 일어나고 있습니다.
C#을 처음 사용하기 시작했을 때 C#이 중간 언어 (IL 또는 MSIL)로 번역된 다음 JIT( Just-In-Time ) 컴파일을 통해 운영 체제의 기본 형식으로 컴파일되었다는 사실을 기억하실 것입니다 . (C#이 2000년에 출시되었을 때는 Microsoft가 Windows와 긴밀하게 연결되어 있었기 때문에 이는 다소 관련성이 없어 보였습니다.)
그러나 Regex는 자체 노드, 구문 분석 트리 및 작업을 생성한 다음 이를 IL로 변환합니다. Regex는 .NET보다 약 반세기 정도 오래된 기술입니다. 이는 이를 처리할 때 특별한 규칙이 있는 이유를 부분적으로 설명합니다.
Compile 플래그가 없으면 인스턴스화된 Regex 개체는 위의 내부 작업 집합으로 해석됩니다. 이러한 작업 코드는 객체에 대한 메서드(예: _Match_)가 호출될 때 JIT 컴파일러가 실행할 수 있도록 IL로 변환됩니다. Regex 호출을 거의 하지 않는 경우에는 괜찮습니다. Regex 정의가 static 이면 작업 코드가 캐시 됩니다 . 기본적으로 가장 최근에 사용한 작업 코드 15개가 캐시됩니다. 많은 스키마를 사용하는 경우 Regex.CacheSize 속성을 사용하여 이 설정을 변경할 수 있습니다.
Compile 플래그를 사용하는 경우 미리 컴파일된 정규식은 시작 시간을 늘리지만 개별 패턴 일치 방법의 실행은 더 빠릅니다. 특정 패턴을 반복적으로 사용하는 경우 유용합니다.
Regex 개체와 스키마를 생성하고, 컴파일하고, 독립 실행형 어셈블리 에 저장할 수 있습니다 . Regex.CompileToAssembly 메서드를 호출하여 컴파일하고 저장할 수 있습니다. 그러나 애플리케이션을 별도의 어셈블리로 분할하므로 디자인할 때 이를 고려하는 것이 좋습니다.
결론적으로 Regex는 시간이 중요한 영역에서는 전혀 사용되어서는 안 된다는 점을 깨닫는 것이 현명합니다. 표현식을 거의 실행하지 않는 경우 일반적인 해석 방식으로 실행하는 것이 가장 좋습니다. 동일한 패턴을 자주 실행하는 경우 Compile 플래그를 사용하거나 별도의 어셈블리에 배치하세요. 궁극적으로 Regex 방법을 분리하고 벤치마크를 사용하여 비교를 확인할 수 있다면 타임 킬러가 작동하는 것을 포착할 수 있습니다.
오픈 소스 Hongmeng을 포기하기로 결정했습니다 . 오픈 소스 Hongmeng의 아버지 Wang Chenglu: 오픈 소스 Hongmeng은 중국에서 유일하게 기초 소프트웨어 분야의 건축 혁신 산업 소프트웨어 행사입니다. OGG 1.0이 출시되고 Huawei는 모든 소스 코드를 제공합니다. Google 리더가 "코드 똥 산"에 의해 사망했습니다 Ubuntu 24.04 LTS 공식 출시 Fedora Linux 40 공식 출시 전에 Microsoft 개발자 : Windows 11 성능이 "어리석을 정도로 나쁩니다", Ma Huateng과 Zhou Hongyi가 악수하며 "원한을 제거합니다" 유명 게임 회사가 새로운 규정을 발표했습니다. 직원의 결혼 선물은 10만 위안을 초과할 수 없습니다. 핀둬둬는 부정 경쟁 혐의로 판결을 받았습니다. 보상금은 500만 위안입니다.이 기사는 Yunyunzhongsheng ( https://yylives.cc/ ) 에 처음 게재되었습니다 . 누구나 방문하실 수 있습니다.