2017-01-28 9 views
1

오브젝트의 ListCollections 이벤트 핸들러가 더 이상 필요하지 않은 오브젝트에 대한 참조를 유지 보수했기 때문에 CodeFluent에서 메모리 부족 문제가 발생했습니다. 해결책은 ListCollection 대신 Entity의 컬렉션 유형을 List로 변경하는 것이 었습니다. 이로 인해 메모리 누출 문제가 해결되었습니다.CodeFluent에서 List를 사용할 때 콜렉션이 느림

그러나 List가 ListCollection보다 훨씬 느리다는 것을 알았습니다. Codefluent는 객체가 이미 목록에 있는지 여부를 검사 할 때마다 객체를 목록에 추가합니다. 그러면 BaseContains 메서드가 실행됩니다. 91 %의 CPU가 여기에서 사용됩니다 (ANTS를 사용하여 프로파일 링). 핫 경로에 CPU 비율을 표시했습니다.

for (readerRead = reader.Read(); ((readerRead == true) 
      && ((count < this.MaxCount) 
      && (count < pageSize))); readerRead = reader.Read()) 
{ 
    readCount = (readCount + 1); 
    if ((CodeFluent.Runtime.CodeFluentPersistence.CanAddEntity(pageIndex, pageSize, pageOptions, readCount) == true)) 
    { 
     Runtime.CwObject cwObject = new Runtime.CwObject(); 
     ((CodeFluent.Runtime.ICodeFluentEntity)(cwObject)).ReadRecord(reader); 
     91% CPU >> if ((this.BaseContains(cwObject) == false)) 
     { 
      this.BaseAdd(cwObject); 
      count = (count + 1); 
     } 
     cwObject.EntityState = CodeFluent.Runtime.CodeFluentEntityState.Unchanged; 
    } 
} 

이 호출 :

protected virtual bool BaseContains(Runtime.CwObject cwObject) 
     { 
      if ((cwObject == null)) 
      { 
       return false; 
      } 
      91% CPU >> bool localContains = this.BaseList.Contains(cwObject); 
      return localContains; 
     } 

이 호출

public virtual bool Equals(Runtime.CwObject cwObject) 
    { 
     if ((cwObject == null)) 
     { 
      return false; 
     } 
     29% CPU >> if ((this.Guid.Equals(CodeFluentPersistence.DefaultGuidValue) == true)) 
     { 
      return base.Equals(cwObject); 
     } 
     45% CPU >> return (this.Guid.Equals(cwObject.Guid) == true); 
    } 

모든 방법이 빛을 보인다

함수 LoadByMainCwEntity는 다음과 같은 코드 블록을 포함하고 있습니다. 나는 문제가 히트작에 있다고 생각한다. 100.000 개의 객체 목록이 있고 Codefluent가 100.001을 추가하면 100,000 명의 다른 모든 객체를 검사하여 일치하는 것을 찾습니다. 컬렉션이 커지면 .Add 메소드가 기하 급수적으로 느려집니다.

Codefluent의 정상적인 '로드'작업에서 개체가 이미 컬렉션에 있는지 확인하는 것이 약간 이상한 것 같습니다. 어떤 해결 방법이 있습니까? 아니면 큰 목록이 Codefluent에서 실제로 느려지는 사실을 가지고 살아야합니까?

+0

사실 나는 collections/list/100000+ objets가 무엇이든간에 조작하지 않을 것입니다.NET (관계형 데이터베이스가 강점이고 일련의 작업을 조작하는 것)이 있다면 BaseContains 호출을 제거하는 측면을 작성할 수 있습니다. 실제로 필요한 경우 병목 현상을 지적하므로 필요하지 않을 것입니다. (CodeFluent가 확신 할 수없는 것) –

답변

1

SoftFluent는 일부 검사를 제거하고 일반성 : blog post, code on GitHub을 제거하여 생성 된 코드의 성능을 향상시키는 부분을 만들었습니다. 이 측면을 사용하여 Frans Bouma가 제공 한 벤치 마크에서 CodeFluent Entities는 손으로 코딩 한 쿼리 바로 다음에서 2 위를 차지합니다.

응용 프로그램의 컨텍스트에서 느린로드 메서드를 식별 한 경우 생성 된 코드를 사용하여 사용자 지정 컬렉션을 반환하는 사용자 지정 C# 메서드를 만들 수 있습니다. 당신이 표면에 속성을 선택하면 fastReader 속성은 속성 표에서 볼 수 있어야합니다

static IEnumerable<Order> LoadOrders() 
{ 
    using (IDataReader reader = OrderCollection.PageDataLoadAll(null)) 
    { 
     while (reader.Read()) 
     { 
      Order o = new Order(); 
      o.RaisePropertyChangedEvents = false; 
      ((ICodeFluentEntity)o).ReadRecord(reader); 
      yield return o; 
     } 
     CodeFluentPersistence.CompleteCommand(Constants.NorthwindStoreName); 
    } 
} 

업데이트 : 예를 들어 대신 생성 된 콜렉션의 IEnumerable<T>를 반환하는 방법을 만들 수 있습니다.

Aspects and producers Properties

속성은 the aspect에 의해 추가됩니다 : 당신은 "화면 및 생산자 등록 정보"탭을 선택해야합니다

<cf:descriptor name="fastReader" targets="Property" defaultValue="false" displayName="Enable Fast Reader" typeName="boolean" description="Determines if the fast reder is enabled for collection loading." category="Faster Reader Aspect" /> 

가로 세로 자동 변환 (CodeFluentPersistence.GetReaderValue)를 제거하고 저장 프로 시저가 반환 할 것으로 예상 모든 열. 경우에 따라 작동하지 않을 수도 있습니다.

+0

안녕 Meziantou, 나는 당신의 제안을 시도했지만 실제로 어플리케이션의 일부는 ~ 450 배 빠릅니다. 와우! 엔티티에서 "fastReader"속성 값을 설정하는 방법을 파악할 수 없었기 때문에 작동 방식을 변경해야했습니다. 나는 새 속성이 속성 편집기에 표시 될 것으로 예상 했었지만 그것을 볼 수는 없습니다. 추가 질문이 2 개 있습니다. 1) 속성 값 "fastReader"를 어떻게/어떻게 설정합니까? 2) 모든 개체에 특성을 설정하지 않는 이유 중 하나를 생각해 볼 수 있습니까? –

+0

그런데 '해결'방법의 측면에는 처리되지 않은 예외가 있습니다. 다음 줄 때문에 변수 'Property'가 null 인 경우 프로젝트가 빌드되지 않습니다. \t \t \t Console.WriteLine ("Property : Property.IsNullable +"Property.IsNullable + "mn :" + Property.IsModelNullable); if (Property == null)로 변경하면 { \t \t \t Console.WriteLine ("Property is null"); 다른 } { \t \t \t Console.WriteLine ("소품 :"+ Property.Name + "널 (NULL) :"+ Property.IsNullable + "백만 :"+ Property.IsModelNullable); } 작동합니다. –

+0

지금 속성을 볼 수 있지만 속성 자체가 아니라 속성에 특성이 설정된 이유가 혼란 스럽습니다. 사실, 속성에 aspect를 설정하면 아무 일도 일어나지 않습니다. 필자가 붙여 넣기를 잘라내어 cfp의 엔티티에 대한 코드를 예상대로 작동합니다. 애스펙트를 디버깅 할 때 엔티티가 아닌 애스펙트의 애스펙트 값을 봅니다. –