2017-02-28 1 views
0

Excel 스프레드 시트를 읽으려면 DocumentFormat.OpenXml을 사용하고 있습니다.OpenXml Excel 스프레드 시트 도구에서 SharedStringTable의 값을 검색하는 성능을 어떻게 향상시킬 수 있습니까?

var returnValue = sharedStringTablePart.SharedStringTable.ChildElements.GetItem(parsedValue).InnerText; 

난을 보장하기 위해 사전을 만들었습니다 : 나는 SharedStringTable 개체에서 셀 값을 조회하는 데 사용되는 코드를 사용하여 성능 병목이 (가 셀 ​​값에 대한 조회 테이블의 일종 것 같다) 한 번만 값을 검색합니다.

if (dictionary.ContainsKey(parsedValue)) 
{ 
    return dictionary[parsedValue]; 
} 

var fetchedValue = sharedStringTablePart.SharedStringTable.ChildElements.GetItem(parsedValue).InnerText; 
dictionary.Add(parsedValue, fetchedValue); 
return fetchedValue; 

따라서 성능 시간이 거의 50 % 나 줄었습니다. 그러나 내 측정 기준에 따르면 코드 라인이 SharedStringTable 객체의 값을 가져 와서 123,951 번 실행하는 데 여전히 208 초가 걸리는 것으로 나타났습니다. 이 작업을 최적화하는 다른 방법이 있습니까?

답변

3

필자는 필요에 따라 각 값을 검색하는 대신 전체 공유 문자열 테이블을 한 번에 사전에 읽습니다. 이렇게하면 파일을 순서대로 이동하고 필요한 값마다 SST를 검색하는 것보다 더 효율적으로 해시 된 조회를 위해 값을 숨길 수 있습니다.

프로세스 시작시 다음과 같이 실행하면 dictionary[parsedValue]을 사용하여 각 값에 액세스 할 수 있습니다. 60000와 파일을 사용하여 내 컴퓨터에

private static void LoadDictionarySax() 
{ 
    using (OpenXmlReader reader = OpenXmlReader.Create(sharedStringTablePart)) 
    { 
     int i = 0; 
     while (reader.Read()) 
     { 
      if (reader.ElementType == typeof(SharedStringItem)) 
      { 
       SharedStringItem ssi = (SharedStringItem)reader.LoadCurrentElement(); 
       dictionary.Add(i++, ssi.Text != null ? ssi.Text.Text : string.Empty); 
      } 
     } 
    } 
} 

: 파일이 매우 큰 경우

private static void LoadDictionary() 
{ 
    int i = 0; 

    foreach (var ss in sharedStringTablePart.SharedStringTable.ChildElements) 
    { 
     dictionary.Add(i++, ss.InnerText); 
    } 
} 

, 파일이 아닌 위의 DOM 접근 방식을 읽을 SAX 방식을 사용하여 약간의 이득을 볼 수 있습니다 행 및 2 열의 경우 질문에서 GetValue 메서드 대신 위의 LoadDictionary 메서드를 사용하면 약 300 배 빨랐습니다. LoadDictionarySax 메서드는 비슷한 성능을 보였지만 큰 파일 (100000 행 10 열)에서 SAX 방법은 LoadDictionary 메서드보다 약 25 % 빠릅니다. 더 큰 파일 (100000 행, 26 열)에서 LoadDictionary 메서드는 메모리 부족 예외를 던졌지 만 LoadDictionarySax은 문제없이 작동했습니다.

+0

나는이 접근법을 정말 좋아합니다. LoadDictionary()에서 셀 값 (숫자 및 조회 값)이 사전 키에 정확히 매핑되도록하려면 어떻게해야합니까? sharedStringTablePart.SharedStringTable.ChildElements의 열거자는 안전한 순서로 0부터 숫자 순으로 반환한다는 가정입니까? –

+0

당신이 좋아하는 것을 기쁘게 생각합니다. 네, 맞습니다. 순서대로 읽혀질 것입니다. 관심이 없다면, 당신이 나에게 묻지 않아도 얼마만큼 성능을 ​​향상 시켰습니까? – petelids

+0

엄청나게, 208 초에서 0.9 초. 이 팁을 공유해 주셔서 감사합니다. 감사합니다. –

관련 문제