2014-02-26 3 views
3

SQL Server에서 Entity Framework를 사용하는 WPF 프로젝트에서 작업합니다. 거기에 최적화가있다. 모든 것이 너무 느립니다. 코드의 어느 부분에서 성능이 저하되는지 진단하고 싶습니다. 제대로 설계되지 않았고 성능이 떨어지는 경우가 거의 없습니다.많은 메서드의 실행 시간 측정

이제 모든 테이블에 대해 클래스가 있습니다 (예 : UserRepository). 정확히 저장소 패턴이 아닙니다. 이러한 클래스에는 다음과 같은 메서드가 있습니다. GetAll(...), GetById(...), GetNewest(...), GetAllWithHigherSalaryThan(int salary, int companyId) 등등, db에 대한 많은 메서드 접근 자입니다. 데이터베이스는 저장소 클래스에서만 사용됩니다.

리팩토링에 대해 이야기하고 싶지 않습니다. 난 단지 모든 메소드가 실행되는 시간과 실행 중에 얼마나 많은 시간이 실행되었는지를 측정하고자합니다. 그 정보로 나는 벌레를 발견 할 수있을 것이다.

많은 클래스에서 "db에서 선택"하는 메소드를 약 100 ~ 측정하고 싶습니다. SQL Server Profiler는 이러한 메서드가 무수히 실행되고 가능한 경우 Profiler에서 로그를 분석하는 것이 데이터베이스에 대한 접근 방식이 아니므로 속임수가 아닙니다.

샘플 방법 :

public IEnumerable<Foo> GetFoo(int y, int z) 
{ 
     return Context.Where(p => 
      p.X == null && 
      p.Y == y && 
      p.Time >= z).OrderBy(x => x.Time).AsEnumerable(); 
} 

지금은 모든 방법에 스톱워치를 추가 실행 시간을 측정, 실행을 계산하고 일부 싱글 또는 무언가에 전달 대해 생각했다

, 다음을 표시합니다. 물론이 진단을 끝내면이 진단 도구를 끄 겠지만이 방법은 모든 방법을 편집해야하는 매우 주일간의 과정이며 이후에 사용하지 않으려면 어떻게해야할지 모르겠다. 어쨌든 #define DEBUG과 같은 것 같지만 절름발이입니다.

리플렉션을 사용하여 효과를 얻으려는 시도가있었습니다. 아마도 C#의 메서드 실행 시간을 볼 수있는 방법이 있습니까?

무엇이 좋습니다?

+0

VS 프로파일 러를 사용해 보았습니까? VS2012 이상에서는 꽤 좋습니다. – BradleyDotNET

+0

당신은 [Entity Framework Profiler?] (http://www.efprof.com)를 보았습니까? 꽤 멋진 소프트웨어 조각입니다. –

답변

0

언어 자체에 내장 된 프로파일 러가 없습니다. IDE/디버거 에는 사용하고있는 것을 지정하는 데 신경 쓰지 않으면 내장 된 프로파일 러가 있습니다.

표시된대로 MSSQL을 실행중인 경우 나중에 작동하는 방식으로 프로파일하지 못할 수 있습니다. 여기에 나를 위해 마술 일한 두 쿼리의 :

SELECT TOP 10 SUBSTRING(qt.TEXT, (qs.statement_start_offset/2)+1, 
((CASE qs.statement_end_offset 
WHEN -1 THEN DATALENGTH(qt.TEXT) 
ELSE qs.statement_end_offset 
END - qs.statement_start_offset)/2)+1), 
qs.execution_count, 
qs.total_logical_reads, qs.last_logical_reads, 
qs.total_logical_writes, qs.last_logical_writes, 
qs.total_worker_time, 
qs.last_worker_time, 
qs.total_elapsed_time/1000000 total_elapsed_time_in_S, 
qs.last_elapsed_time/1000000 last_elapsed_time_in_S, 
qs.last_execution_time, 
qp.query_plan 
FROM sys.dm_exec_query_stats qs 
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt 
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp 
ORDER BY qs.total_logical_reads DESC -- logical reads 
-- ORDER BY qs.total_logical_writes DESC -- logical writes 
-- ORDER BY qs.total_worker_time DESC -- CPU time 

source

SELECT DISTINCT TOP 10 
t.TEXT QueryName, 
s.execution_count AS ExecutionCount, 
s.max_elapsed_time AS MaxElapsedTime, 
ISNULL(s.total_elapsed_time/s.execution_count, 0) AS AvgElapsedTime, 
s.creation_time AS LogCreatedOn, 
ISNULL(s.execution_count/DATEDIFF(s, s.creation_time, GETDATE()), 0) AS FrequencyPerSec 
FROM sys.dm_exec_query_stats s 
CROSS APPLY sys.dm_exec_sql_text(s.sql_handle) t 
ORDER BY 
s.max_elapsed_time DESC 
GO 

source

여기에 마법이 있는지에 관계없이 전반적으로 대부분의 시간을 차지 명령하는 알아낼 수있다 아주 천천히 10 번 명령을 실행하거나 매우 빠르게 1,000,000 번 실행하는 명령.

조금 더 높은 곳에서 벗어날 수도 있습니다. 이전에 프로파일 러를 각 웹 요청의 시작과 끝 부분에 연결하여 프로젝트를 디버그 할 수 있었지만 문제의 원인이되는 특정 명령을 찾을 수는 없습니다.

4

제 첫 번째 추천 정보는 적절한 프로파일 러입니다. 나의 즐겨 찾기는 Jetbrains의 dotTrace이지만 다른 것들도 있습니다.

어떻게 든 경우 그 옵션을 선택하지 않습니다 그리고 당신은 그것을 스스로 할 주장 :

내가 Postsharp 추천 - 또는 다른 AOP 패키지. 가능한 많은 메소드에 aspect를 쉽게 추가 할 수 있습니다. 이것은에 필요한 모든 코드가

#if DEBUG 
[assembly: Trace(AttributeTargetTypes = "MyNamespace.*", 
    AttributeTargetTypeAttributes = MulticastAttributes.Public, 
    AttributeTargetMemberAttributes = MulticastAttributes.Public)] 
#endif 

:

[Serializable] 
public class TraceAttribute : OnMethodBoundaryAspect 
{ 
    public override void OnEntry(MethodExecutionArgs args) 
    { 
     // start measuring time here 
    } 

    public override void OnExit(MethodExecutionArgs args) 
    { 
     // stop measuring here 
    } 
} 

그런 다음 당신이 방법의 무리 (MyNamespace에 모든 public 메소드)에 그 부분을 적용 Postsharp와

당신은 측면 쓰기 한 번에 많은 방법을 도구로 삼는다.

최근에 나는 모든 측정 값을 csv 텍스트 파일에 버린 다음 SQL Server에 버렸습니다. 거기서 선택과 그룹화를 쉽게 할 수있었습니다. 예를 들어 메서드에서 소비 한 총 시간을 확인할 수있었습니다. 프로덕션 환경에서 측정을했기 때문에 프로파일 러를 사용하지 않았습니다. 계측기로 인한 성능 저하는 프로그램의 속도가 느린 경우 큰 영향을주지 않았습니다.

여기가에 대한 추가 정보를 원하시면입니다 : - PostSharp 익스프레스 - http://www.postsharp.net/aspects/examples/logging

그리고 심지어는 무료 버전 그렇게 충분하다.

+0

나는이 깨끗한 접근 방식을 좋아한다. 또한 동일한 방법을 사용하는 래퍼 메서드를 사용하는 접근 방식을 사용했지만 실행 시간 및 기타 데이터를 데이터베이스에 기록하는 로깅 프레임 워크의 일부였습니다. 여기, 당신의 접근 방식이 잘 맞는 것 같아요. –