직접 선택 문에서 Entity Framework가 Dapper보다 빨리 수행되는 이유

c# dapper entity-framework

문제

데이터베이스를 다루는 데 ORM을 사용하는 것이 처음입니다. 현재 새 프로젝트를 만들고 있으며 Entity Framework 또는 Dapper를 사용할 것인지 결정해야합니다. Dapper가 Entity Framework보다 빠르다는 많은 기사를 읽었습니다.

그래서 저는 Dapper를 사용하는 간단한 프로토 타입 프로젝트 2 개를 만들고 다른 하나는 Entity Framework를 사용하여 한 테이블에서 모든 행을 가져옵니다. 다음 그림과 같은 테이블 스키마

테이블 스키마

두 프로젝트의 코드는 다음과 같습니다.

Dapper 프로젝트 용

System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
IEnumerable<Emp> emplist = cn.Query<Emp>(@"Select * From Employees");
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString());

Entity Framework 프로젝트 용

System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
IEnumerable<Employee> emplist = hrctx.Employees.ToList();
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString());

위의 코드를 여러 번 시도한 후에 처음으로 프로젝트를 실행하면 더 깔끔한 코드가 빨라지고 처음으로 엔티티 프레임 워크 프로젝트에서 더 나은 결과를 얻을 수 있습니다. 또한 엔티티 프레임 워크 프로젝트에서 다음과 같은 진술을 시도하여 게으른 로딩

hrctx.Configuration.LazyLoadingEnabled = false;

그러나 동일한 EF는 처음을 제외하고는 더 빨리 수행됩니다.

웹상의 모든 기사에서 반대 의견을 말하지만,이 샘플에서 EF를 더 빠르게 만드는 것에 대한 설명이나 안내는 누구에게 줄 수 있습니까?

최신 정보

엔티티 샘플에서 코드 줄을 변경했습니다.

IEnumerable<Employee> emplist = hrctx.Employees.AsNoTracking().ToList();

일부 기사에서 언급 한 AsNoTracking 을 사용하면 엔티티 프레임 워크 캐싱이 중단되고 캐싱을 중지 한 후 더 이상 샘플이 더 잘 수행됩니다 (큰 차이는 아닙니다)

인기 답변

ORM (Object Relational Mapper)은 응용 프로그램과 데이터 소스 사이에 레이어를 생성하고 ADO.NET 개체가 아닌 관계형 개체를 반환하는 도구입니다. 이것은 모든 ORM이하는 기본적인 것입니다.

이를 위해 ORM은 일반적으로 쿼리를 실행하고 반환 된 DataReader 를 POCO 클래스에 매핑 합니다. Dapper는 여기까지 제한됩니다.

이를 더욱 확장하기 위해 일부 ORM ( "전체 ORM"이라고도 함)은 응용 프로그램 데이터베이스를 독립적으로 만들고, 향후 호출을 위해 데이터를 캐시하고, 작업 단위를 관리하는 등 더 많은 작업을 수행합니다. 이 모든 것이 훌륭한 도구이며 ORM에 가치를 더합니다. 하지만 비용이 든다. Entity Framework는이 클래스에 속합니다.

쿼리를 생성하려면 EF가 추가 코드를 실행해야합니다. 캐시는 성능을 향상 시키지만 캐시 관리는 추가 코드를 실행해야합니다. 작업 단위 W EF가 제공하는 기타 부가 기능에 대해서도 동일합니다. 이 모든 것이 추가 코드 작성 비용 절약하고 EF는 비용을 지불합니다.

그리고 비용 은 성능입니다. Dapper는 매우 기본적인 업무를 수행하므로 더 빠릅니다. 하지만 더 많은 코드를 작성해야합니다. EF가 그 이상을 수행함에 따라, (조금) 느려집니다. 하지만 코드를 적게 작성해야합니다.

그렇다면 왜 테스트 결과가 반대가되는 것입니까?
실행중인 테스트가 비교할 수 없기 때문입니다.

전체 ORM은 위에서 설명한 많은 좋은 기능을 가지고 있습니다. 그 중 하나가 UnitOfWork입니다. 추적은 UoW의 책임 중 하나입니다. 개체가 처음 요청 (SQL 쿼리)되면 데이터베이스로 왕복 이동합니다. 이 객체는 메모리 캐시에 저장됩니다. 전체 ORM은 이미로드 된 객체에 대한 변경 사항을 추적합니다. 동일한 객체가 다시 요청 된 경우 (로드 된 객체를 포함하는 동일한 UoW 범위의 다른 SQL 쿼리) 데이터베이스 라운드 트립을 수행하지 않습니다. 대신, 그들은 메모리 캐시에서 객체를 반환합니다. 이렇게하면 상당한 시간이 절약됩니다.
Dapper는 테스트에서 더 느리게 수행되는이 기능을 지원하지 않습니다.

그러나이 혜택은 동일한 객체가 여러 번로드 된 경우에만 적용됩니다. 또한 메모리에로드 된 오브젝트 수가 너무 많으면 전체 ORM 속도가 느려지므로 메모리에있는 오브젝트를 확인 하는 데 필요한 시간이 길어집니다. 다시 한번,이 유익은 유스 케이스에 달려있다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.