문제

.NET의 속성을 통해 개별 메소드를 프로파일 할 수 있습니까?

나는 현재 정적 방법을 많이 사용하는 큰 레거시 응용 프로그램에서 병 목을 찾으려고 노력하고 있습니다. 프레임 워크를 통합하는 것은 현재 옵션이 아닙니다. 대부분의 통화는 정적 메소드를 사용하기 때문에 인터페이스 및 종속성 주입을 사용할 수 없습니다. 로그 진단으로 코드를 해킹하는 것도 실행 가능한 솔루션이 아닙니다.

시장에는 프로파일 링 도구가 있다는 것을 알고 있지만 현재 예산을 벗어납니다. 이상적으로는 메소드 입력 및 메소드 종료에 대한 몇 가지 기본 정보를 기록하는 고유 한 사용자 정의 속성을 만들 수 있습니다. 나는 실제로 사용자 정의 속성으로 작업 한 적이 없으므로 이것이 가능한지에 대한 통찰력이 높아질 것입니다.

가능하면 구성 파일을 통해 프로파일 링을 활성화하고 싶습니다. 이것은 단위 및 통합 테스트를 통한 프로파일 링을 지원합니다.

도움이 되었습니까?

해결책

당신은 당신이하고있는 일에 속성을 사용할 수 없습니다. 그러나 몇 가지 선택 사항이 있습니다.

첫째, 많은 프로파일러 도구 (예 : Redgate 개미)는 상대적으로 저렴하고 ($ 200- $ 300) 사용하기 쉬우 며 대부분 몇 주 동안 무료 평가 기간을 제공하므로 구매 여부를 결정하기 전에 필요한 리프트를 제공 할 수 있는지 확인할 수 있습니다. 또한, .NET CLR 프로파일 러 무료로 다운로드 할 수 있습니다.

그것이 불가능하다면, PostSharp는 아마도 그러한 논리를 코드에 직조하는 가장 쉬운 방법 일 것입니다.

마지막으로, 어떤 이유로 든 PostSharp를 사용할 수없고 코드에 속성을 기꺼이 추가하려는 경우, 사용 블록의 형태로 각 방법에 간단한 계측 블록을 추가 할 수 있습니다.

public void SomeMethodToProfile()
{
    // following line collects information about current executing method
    // and logs it when the metric tracker is disposed of
    using(MetricTracker.Track(MethodBase.GetCurrentMethod()))
    { 
        // original code here...
    }
}

일반적인 MetricTracker 구현은 다음과 같습니다.

public sealed class MetricTracker : IDisposable
{
    private readonly string m_MethodName;
    private readonly Stopwatch m_Stopwatch;

    private MetricTracker( string methodName ) 
       { m_MethodName = methodName; m_Stopwatch = Stopwatch.StartNew(); }

    void IDisposable.Dispose()
       { m_Stopwatch.Stop(); LogToSomewhere(); }

    private void LogToSomewhere()
       { /* supply your own implementation here...*/ }

    public static MetricTracker Track( MethodBase mb )
       { return new MetricTracker( mb.Name ); }
}

다른 팁

당신은 사용할 수 있습니다 포스트 쇼트 일부 직조를 수행하려면 기본적으로 회전합니다.

[Profiled]
public void Foo()
{
     DoSomeStuff();
}

~ 안으로

public void Foo()
{
    Stopwatch sw = Stopwatch.StartNew();
    try
    {
        DoSomeStuff();
    }
    finally
    {
        sw.Stop();
        ProfileData.AddSample("Foo", sw.Elapsed);
    }
}

실제로 PostSharp 문서를 살펴보면 사용할 수 있어야합니다. 지브롤터 (PostSharp와 함께)이를 위해, 당신이 그것을 감당할 수 있다면. 그렇지 않으면 하루를 보내면 PostSharp의 매달려 가면 여전히 가치가있을 수 있습니다.

프레임 워크를 코드베이스에 통합 할 여유가 없다고 말했지만 PostSharp가 코드에서 컴파일 포스트 컴파일 변환을 실행하도록하는 것만 큼 "통합"하는 것은 아닙니다.

나는 당신이 묘사 한 것과 매우 비슷한 것을 찾고있었습니다. 나는 그런 프레임 워크를 찾을 수 없어서 내 자신을 굴 렸습니다. 나는 이것이 있다는 점에 주목해야한다 매우 간단합니다, 그러나 때로는 단순한 것이 좋습니다!

벤치마킹이 단위 테스트를 만나는 것으로 설명합니다. 개념은 속도를 측정하거나 비교하기 위해 코드 섹션을 분리하는 것입니다.

속성 사용의 일반적인 예는 다음과 같이 보입니다.

[ProfileClass]
public class ForEachLoopBenchmarks
{
    [ProfileMethod]
    public void ForLoopBenchmark()
    {
        List<int> list = GetNumberList();

        for (int i = 0; i < list.Count; i++)
        {
        }
    }

    [ProfileMethod]
    public void ForEachLoopBenchmark()
    {
        List<int> list = GetNumberList();

        foreach (int i in list)
        {
        }
    }

    private List<int> GetNumberList()
    {
        List<int> list = new List<int>();
        for (int i = 0; i < 1000; i++)
        {
            list.Add(i);
        }
        return list;
    }
}

그런 다음 콘솔 앱을 만들고 아래 코드를 기본 방법 및 속성으로 장식 된 이전에 설명 된 클래스가 포함 된 어셈블리에 대한 참조를 추가하십시오. 각 방법의 실행 시간 (1000 회 실행)이 콘솔에 출력됩니다.

class Program
{
    static void Main(string[] args)
    {
        ProfileRunner rp = new ProfileRunner();
        rp.Run();
    }
}

콘솔 출력은 다음과 같이 보입니다.

console output

참조를 추가해야합니다 punit.dll 콘솔 애플리케이션 및 속성으로 표시된 메소드가 포함 된 클래스 라이브러리에.

당신은 이것을 패키지로 얻을 수 있습니다 너겟 여기.

nuget 명령 : PM> 설치 패키지 펀칭

오히려 전체 소스 코드를 찾으려면 찾을 수 있습니다. github 여기.

나는이 질문에서 실제로 실행 시간을 측정하는 방법을 기반으로합니다. https://stackoverflow.com/a/1048708/1139752

나는 다음에 구현을 더 자세히 다룹니다. 블로그 게시물.

또한 있습니다 약간 볼만한 가치가있는 무료 프로파일 러 도구.

C#에서 성능 튜닝을합니다. 내가 필요한 것은이 기술입니다. 큰 문제가 아닙니다.

간단한 아이디어를 기반으로합니다. 필요한 것보다 훨씬 오래 기다리고 있다면,이 프로그램의 일부는 실제로 수행 할 필요가없는 일이 필요한 것보다 훨씬 오래 기다리고 있음을 의미합니다.

그리고 어떻게 기다리고 있습니까? 거의 항상 통화 사이트에서 통화 스택에서.

따라서 기다리는 동안 잠시 멈추고 전화 스택을 보면 기다리고있는 것이 무엇인지 알 수 있으며 실제로 필요하지 않은 경우 (일반적으로 그렇지 않은 경우) 왜 즉시 알 수 있습니다.

하나의 샘플 만 믿지 마십시오. 몇 번하십시오. 둘 이상의 스택 샘플에 나타나는 것은 무엇인가에 대해 무언가를 할 수 있다면 많은 시간을 절약 할 수있는 것입니다.

알다시피, 타이밍 기능이나 그들이 몇 번이라고 부르는지 계산하는 것이 아닙니다. 그것은 프로그램에 몇 번 발표되지 않은 프로그램에 들어가서 그것이 무엇을하고 있는지, 그 이유를 물어 보는 것입니다. 무언가가 80% (또는 20% 이상)를 낭비한다면, 사이클의 80%가 진정으로 필요하지 않은 상태에있게되므로, 그냥 내려 놓고 살펴보십시오. 정밀 측정이 필요하지 않습니다.

큰 문제와 함께 작동합니다. 또한 작은 문제와 함께 작동합니다. 그리고 모든 일을 두 번 이상 수행하면 프로그램이 빨라짐에 따라 작은 문제가 비교적 커지고 찾기가 더 쉬워집니다.

당신은 다음과 같은 것을 통해 측면 지향 프로그래밍을 사용하지 않는 한 속성을 통해이를 구현할 수 없습니다. 포스트 쇼트 이것을 달성하기 위해.

그러나 Define (잠재적으로 빌드 구성에 설정)을 기반으로 조건부 로직을 넣을 수 있습니다. 현재 컴파일 설정에 따라 타이밍으로 로깅을 켜거나 끌 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top