2009-05-19 3 views
1

더 빨리 알고 싶습니다. 도와주세요. 당신이 정규 표현식을 반환 볼 수 있듯이로컬 변수와 메소드에서 호출 된 변수의 차이점은 무엇입니까? C#

public static Regex FindNumber() 
{ return new Regex(@"\d+", RegexOptions.IgnoreCase | RegexOptions.Compiled); } 

:

는 그래서 같은 방법으로 선언 된 변수가 있습니다.

나 또한 그렇게 보이는 또 다른 방법이 있습니다 TestTwo 지금

private static string TestOne(string RawData) 
{ 
    Regex rgxFindNumber = FindNumber(); 
    Regex rgxFindDays = FindDays(); 
    for (int i = 0; i < mc.Count; i++) 
    { 
     int days = Convert.ToInt32(rgxFindNumber.Match(rgxFindDays.Match(mc[i].Value).Value).Value); 
    } 
    return RawData; 
} 

을 TestOne 방법이 더 빠를 것 또는이다? TestOne 그래서 난 구현하는 더 나은 것 알고 싶습니다 내 코드에서 aweful 많은 전화를받을 수 있기 때문에

 private static string TestTwo(string RawData) 
{ 
    for (int i = 0; i < mc.Count; i++) 
    { 
     int days = Convert.ToInt32(FindNumber().Match(FindDays().Match(mc[i].Value).Value).Value); 
    } 
    return RawData; 
} 

지금 호기심 메신저.

감사합니다.

** 편집 : ** 사용하고있는 코드는 매우 큰 클래스입니다. 텍스트 기반 전략 게임을위한 텍스트 파서입니다. 나는 그것을 조금 리팩터링하려고 노력하고 있는데, 여기서 궁금해하는 것이있다. 정규식에 대한 개인 변수를 만들면 클래스에 액세스 할 때마다 실행되지 않습니까? 그게 내 질문이야.

+0

첫 번째는 의미있는 성능 목표를 설정합니다. SECOND, 목표 달성을위한 진척 상황을 측정하십시오. 셋째, 목표를 달성하지 못한 경우 프로파일 러를 사용하여 가장 느린 것을 찾으십시오. 넷째, 고쳐주세요. 목표를 달성 할 때까지 반복하십시오. 각 단계가 중요합니다. 귀하의 질문에 대답하는 유일한 방법은 그것을 피하고 결과를 측정하여 그것이 의미있는지를 확인하는 것입니다. 귀하의 질문을 읽는 책상에 앉아있는 누구도 고객의 기계에 얼마나 큰 차이가 있는지, 또는 그 차이가 고객에게 의미가 있는지 또는 고객이 최적화 할 곳을 찾아야 할지를 알 수 있습니다. –

답변

4

TestOneTestTwo보다 빠른 것입니다.

이 두 가지 이점이 있습니다

  • 구문 분석하고 정규 표현식은 한 번만 수행을 위해 개체를 구성하는 데 사용되는 시간, 대신 mc.Count 번 가비지 컬렉션에
  • 적은 압력 적은 수의 개체가 구축되어 있기 때문에합니다.

그러나 한 걸음 앞으로 나아갈 것입니다. 만약 당신이 항상 같은 정규 표현식을 리턴 할 것이고 속도에 대해 걱정한다면 정적 필드에 그 정규 표현식 객체를 캐시 할 것입니다.

private static Regex _FindNumber; 
public static Regex FindNumber() 
{ 
    if (_FindNumber == null) 
     _FindNumber = new Regex(@"\d+", RegexOptions.IgnoreCase | RegexOptions.Compiled); 
    return _FindNumber; 
} 

이것은 단지 하나의 객체, 총을 만들 것이고, 그것을 주변에 계속 :

예를 들어, 당신은이를 고려할 수 있습니다.

그러나 여기에 내 대답이 있습니다.

어느 것이 가장 빠를 것인지 실제로 알기 위해서는 코드를 측정해야하며, 선택적으로 좋은 대안을 위해 내 변형을 넣은 다음 결정해야합니다. 하드 데이터없이 최적화를 결정하지 않으면 코드를 다시 작성하는 데 드는 시간을 낭비하게 될 수 있습니다. 새로운 버그가 생길 수 있습니다. 수정해야 할 수정이 필요하며, 성능을 1 % 향상시키는 데 더 많은 시간을 할애 할 수 있습니다.

정렬 알고리즘의 유형을 변경하는 것과 같이 큰 최적화가 알고리즘 적으로 수행 된 다음 필요에 따라 루프 튜닝과 같은 로컬 최적화로 이동합니다.

그런 말로하면, 적어도 루프 상에 객체를 만드는 것을 피할 것입니다. 그것은 상식 일뿐입니다.

+0

womps 응답에 설명 된대로이 설명을 반복 할 예정입니다. 여전히 적용되기 때문입니다. 사용중인 코드의 클래스가 매우 큽니다. 텍스트 기반 전략 게임을위한 텍스트 파서입니다. 나는 그것을 조금 리팩터링하려고 노력하고 있는데, 여기서 궁금해하는 것이있다. 정규식에 대한 개인 변수를 만들면 클래스에 액세스 할 때마다 실행되지 않습니까? 그게 내 질문이야. –

+0

Scott : 위에 제공된 코드는 FindNumber 정적 속성에 처음 액세스 할 때 _FindNumber에 저장된 Regex를 만들고 프로그램이 끝날 때까지 계속 존재합니다. – Powerlord

+0

새로운 Regex 객체를 반환하는 메소드를 호출 할 때마다 새로운 Regex 객체가 생성됩니다.이 객체는 생성에 시간이 걸리고 GC 압력을 추가합니다.다음 번에 동일한 함수를 호출 할 때 해당 객체를 캐시하면 이전에 생성 된 객체를 가져오고 시간과 GC 압력을 절약 할 수 있습니다. 함수를 호출하고 루프에서 루프를 반복하지 않으면 더 많은 오브젝트를 생성하고 더 많은 GC 압력을 추가하기 때문에 각 루프 반복에 더 많은 시간이 소요됩니다. 그 질문에 대답합니까? 그렇지 않은 경우 구체적으로 작성하십시오. –

1

TestTwo에서 반복 할 때마다 Regex 개체를 새로 작성하므로 TestOne이 더 빠를 것이라고 저는 믿습니다. FindDaysFindNumber과 동일하게 구현되면 두 개의 객체를 생성 할 때 더 나빠질 것입니다.

1

TestTwo가 FindNumber()를 호출하여 스택 프레임을 추가하기 때문에 기술적으로 TestOne이 빠릅니다.

나는 그것이 얼마나 많은 차이를 만들지 모른다. 나는 그 정도의 의문을 품는다. 당신의 방법은 정적입니다, 그래서 그것은 단지 객체를 생성하는 것입니다, 그것은 꽤 빨라야합니다.

내 질문에 왜 같은 문자열을 반복해서 반환하기 위해 함수 호출을 사용하고 있습니까? 실제 변수를 선언하는 것이 어떨까요? 당신은 모든 루프 반복을위한 새로운 정규 표현식을 생성하지 않는 때문에

처럼,

private static Regex _findNumber = new Regex(@"\d+", RegexOptions.IgnoreCase | RegexOptions.Compiled); 
+0

사용중인 코드의 클래스가 매우 큽니다. 텍스트 기반 전략 게임을위한 텍스트 파서입니다. 나는 그것을 조금 리팩터링하려고 노력하고 있는데, 여기서 궁금해하는 것이있다. 정규식에 대한 개인 변수를 만들면 클래스에 액세스 할 때마다 실행되지 않습니까? 그게 내 질문이야. –

+1

클래스에 액세스 할 때마다? 절대적으로하지. 클래스가 생성 될 때마다, 반드시 하나의 private 변수를 생성해야합니다. 그러나 변수를 역 참조하는 것은 똑같은 일을하는 함수를 호출하는 것보다 빠를 것입니다. – womp

+0

womp라면 그 크기 때문에 한 클래스에 약 100 개의 전용 변수가 생길 것입니다. 그러나 어떤 인스턴스에서든 클래스를 만들 때마다 약 3 또는 4 개 또는 그 변수 만 사용됩니다. 저는 웹 기반 프로그래머입니다. 따라서 포스트 백이 만들어지고 클래스 내부의 메서드가 호출 될 때마다 클래스가 다시 생성된다는 것을 알고 있습니다. 나 맞아? 그래서 새로 생성 된 변수 중 3 번 또는 4 번을 클래스가 '생성'될 때마다 사용하기 때문에 각 클래스를 메소드에 넣는 것이 더 나을 것입니다. 그 맞습니까? –