Microsoft MVP성태의 닷넷 이야기
리플렉션 성능 관련 질문 드립니다. [링크 복사], [링크+제목 복사]
조회: 14279
글쓴 사람
popo
홈페이지
첨부 파일
 

안녕하세요 다음과 같이 DataTable을 특정 모델 클래스의 List<T>타입으로 Convert해서 사용하고 있습니다.

그런데 성능상 데이터가 많은 편이 아닌데도 느린 부분이 있어 혹시 어디 부분에서 성능이 떨어지는지 도움 요청드립니다.

소스는 다음과 같고, 모델 클래스의 각각 Property에 DataTable의 해더명을 어트리뷰트로 정의해서 자동으로 Property의 타입에 맞게 캐스팅해서 속성을 채우는 방식입니다.

테스트시 DataTable에 약 50개 정도의 Row를 List<T>형식으로 변환 했을때 1s ~ 2s사이 정도 시간이 지연 됬습니다.

소스에 문제가 되는 부분이 있는지 도움 요청 드립니다.

public static List<T> DataTableToList<T>(DataTable table) where T : class, new()
        {
            if (table == null) return null;

            try
            {
                List<T> list = new List<T>();

                foreach (DataRow row in table.AsEnumerable())
                {
                    T obj = new T();

                    foreach (PropertyInfo prop in obj.GetType().GetProperties())
                    {
                        try
                        {
                            string headerCaption = null;

                            // 모델 클래스(T) 속성에 설정되어 있는 어트리뷰트 Get
                            object[] atts = prop.GetCustomAttributes(typeof(ExtensionEnumAttribute), false);
                            if (atts != null && atts.Length <= 0)
                            {
                                continue;
                            }

                            ExtensionEnumAttribute att = (ExtensionEnumAttribute)atts[0];
                            if (att == null || att.Objs == null || att.Objs.Length < 0 || string.IsNullOrWhiteSpace(att.Objs[0].ToString()))
                            {
                                headerCaption = prop.Name;
                            }
                            else
                            {
                                // 속성에 설정되어 있는 컬럼 헤더 타이틀 어리트뷰트 값
                                headerCaption = att.Objs[0].ToString();
                            }

                            PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);

                            if (propertyInfo.PropertyType.IsEnum)
                            {
                                object enumVal = Enum.Parse(propertyInfo.PropertyType, row[headerCaption].ToString());
                                propertyInfo.SetValue(obj, enumVal, null);
                            }
                            else
                            {
                                Type t = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;

                                if (row[headerCaption] != DBNull.Value)
                                {
                                    propertyInfo.SetValue(obj, Convert.ChangeType(row[headerCaption], t), null);
                                }
                                else
                                {
                                    propertyInfo.SetValue(obj, null, null);
                                }
                            }
                        }
                        catch(Exception ex)
                        {
                            // 데이터 테이블에 없는 모델 클래스(T) 속성
                            // 예] IsSelectCheck 속성 등..
                            continue;
                        }
                    }

                    list.Add(obj);
                }

                return list;
            }
            catch(Exception ex)
            {
                throw new Exception("데이터 테이블 -> 모델 변환 오류");
            }
        }








[최초 등록일: ]
[최종 수정일: 5/26/2017]


비밀번호

댓글 작성자
 



2017-05-26 02시32분
직접 재보시는 것이 더 빠르지 않을까요? ^^ Stopwatch 클래스를 이용해 어느 부분에서 시간이 더 걸리는 것인지 밝혀낸 다음 왜 그런지 물어보시면 더 좋을 것 같습니다.

참고로, .NET Reflection은 원래 느립니다. (느리다는 말이 매우 상대적인 기준이긴 하지만.)

아울러 다음의 글들도 한번 읽어보시고.

C# 4.0 - dynamic 키워드
; http://www.sysnet.pe.kr/2/0/766

C# - Reflection의 박싱 없이 값 형식을 다루는 방법
; http://www.sysnet.pe.kr/2/0/10866
정성태
2017-05-26 08시47분
일단 리플렉션을 메서드 사용을 최소화하는 게 중요해 보입니다.
GetProperties() 나 GetCustomAttributes() 같은 것들을 캐쉬 처리할 수 있으면 좋을 것 같습니다.
그리고 정성태님이 열거해주신 링크 중 Reflection의 박싱 없이 값 형식을 다루는 방법...에 나오는 LCG 기법이면 박싱도 해결될테구요.
어떤 방식으로 처리하는지 실제 사례를 확인해보시고 싶으시면 github의 dapper를 fork 하셔서 ormapping 하는 코드를 뒤져보시면 도움이 되지 않을까 싶습니다.
Beren Ko

... 16  17  18  19  20  21  22  23  24  25  26  27  28  29  [30]  ...
NoWriterDateCnt.TitleFile(s)
5125게스트2/19/20196949delegate를 활용한 event 를 적절히 불러오고 싶습니다. [2]
5124정근화2/12/20196827윈도우 서버2003 환경 오류 [2]
5123김주현2/8/20196865MS LUIS 에 대한 소개 하실 계획이 있으신가요? [1]
5122jaka...2/1/20198710Clickonce 배포 후 Command 실행 [2]파일 다운로드1
5121엔벌이1/31/20198130C# DataGridView의 MDB파일 함수? ArrayList? [1]파일 다운로드1
5120임우진1/30/20198625웹에서 응용프로그램 바로 실행하기 관련 브라우저에서 파라미터가 넘어오지 않습니다.ㅜㅜ [2]
5119guest1/29/201910021교재에 오탈자 있어 알려드리려 합니다 [1]
5118WPF꿈...1/26/20197942GetHashCode 메서드에 대해서 [1]
5117하주형1/25/20198608List<int>에 대한 이해가 잘안됩니다. [5]
5116게스트1/24/20197359asp.net 관련 gridview webform 질문 드립니다. [1]파일 다운로드1
5115Soul...1/24/20197537투명 패널 질문드립니다. [2]
5114박현일1/20/20197892WPF DataContext 관련 초보 질문을 드려봅니다.^^ [5]
5113하주형1/20/20197139안녕하세요 시작하세요 C# 인코딩관련 질문드립니다. [1]
5112손성배1/19/201916166안녕하세요 cp949 인스톨시 오류입니다... 너무 힘들어요 [5]
5111게스트1/10/20197778암호화 라이센스 관련 문의 드립니다. [1]
5110WPF꿈...1/9/20197414Thread Abort 함수 사용시 [2]
5109닷넷개발1/9/20197387thread 관련 질문 예제.. [2]파일 다운로드1
5108닷넷개발1/9/20198536thread 관련 질문 드립니다.. [4]
5107우코아1/4/201911188WPF에서 로딩중 이미지를 구현 - Project [5]파일 다운로드1
5106우코아1/3/20198819WPF에서 로딩중 이미지를 구현 - Source [1]
5104우코아1/1/201910056WPF에서 로딩중 이미지를 구현 [4]
5103이혜성12/31/20181063732bit .net 으로 만들어진 dll파일 [5]
5102돌고래12/18/20189411자료구조와 알고리즘 도서 관련 질문입니다. [4]
5101세퉁12/17/20187731안녕하세요 wpf 공부중인데 질문있습니다. [4]파일 다운로드1
5100돌고래12/16/20187098도서 추천 부탁드립니다. [1]
5099WPF12/12/201810175안녕하세요. WPF에서 UWP Control을 참조하려고 합니다. [3]파일 다운로드1
... 16  17  18  19  20  21  22  23  24  25  26  27  28  29  [30]  ...