Canvas 위에 많은 Control (약 2 만개) 을 배치하는 방법 문의 입니다.

안녕하세요 계속 윈폼만 사용하던 유저 입니다.
바둑 판처럼 일정한 간격으로 컨트롤을 많이 배치하고
Zoom In/Out, 미니 맵 기능이 필요 하다 보니 WPF가 구현이 좋을 것으로 보여 작업 진행 했었습니다.

Shape 를 상속 받은 class 를 만들었고
클릭 했을 때 테두리 색상, Index 정보 표시가 필요 하여
다음 과 같이 구현 했습니다.

protected override void OnRender(DrawingContext dc)
        {
            base.OnRender(dc);
            

            if (_rect.IsEmpty)
            {
                return;
            }
            
            if (Clicked)
            {
                dc.DrawRectangle(Brushes.Orange, COLOR_CLICKED, _rect);

                var innerRect = _rect;
                innerRect.Inflate(-2, -2); 
                dc.DrawRectangle(this.Fill, null, innerRect);                
            }

            if (string.IsNullOrEmpty(Text) == false)
            {
                Point textPosition = new Point(
                    _rect.X + (_rect.Width - _formattedText.Width) / 2,
                    _rect.Y + (_rect.Height - _formattedText.Height) / 2);
                
                dc.DrawText(_formattedText, textPosition);
            }
        }

동작은 되는데… 전체 셀에 대해 색상 초기화가 엄청 오래 걸립니다.
모든 셀이 색상 변경되는 것 까지 2만개 기준 Text 가 없는 경우는 약 2초 텍스트가 있는 경우는 약 5초 정도 걸리는 것 같습니다.

각 Index의 결과 정보를 한꺼번에 리셋 시키는 경우가 최소 5분에 한번씩을 발생을 하는데…
구현 방식이 잘못된 걸까요? 혹은 다른 방법이 있을까요?

고수 분들의 의견을 듣고 싶습니다.

우선 의심 되는 부분이 선형 구조의 자료구조를 쓰신건 아닌가요?
객체가 특별히 순서가 필요 없다면
List 보다는 Hashset을 쓰는게 속도를 높일 수 있습니다.

내부적으로 List는 속도 제한도 걸리고요.

다음으로 확인 해 볼수 있는 건
성능 프로파일러 입니다.

오래 걸리는 액션 직전에
진단 도구의 CPU 프로파일링을 켜시고

문제가 되는 동작을 하신 후
모두 중단을 시키 세요.

그 후 인사이트게 걸리는게 있다면
가장 최우선으로 수정 하시길 권장 드리고

그 다음은 많이 사용 되는 메소드 들을 잘 살펴 보시면서
개선 필요성이 있는지 검토 해 보시면 어느정도 성능 향상을 보실수 있을겁니다.

답변 감사합니다.

일단 2만개 Sharp 는 Array 로 들고 있고
한꺼번에 색상 변경 시 for 문을 통해 순차적으로 Fill 색상을 변경 합니다.

이것 자체는 TickCount 로 확인 시 100 ms 가 안걸리구요.

변경된 색 반영이 오래 걸립니다.

각각의 Sharp 에 대해서 OnRender 가 발생 하다 보니 Windows Message 가 너무 많아 생기는 문제로 추측되는데… 어떻게 최적화 해야 할지 감을 못 잡고 있습니다…

컨트롤이 아닌
직접 드로잉을 하시는 거라면
skelement 를 추천 드립니다.

2 Likes

SkiaSharp 는 전혀 몰랐네요.

내용 찾아 보겠습니다. 감사합니다!

1 Like

SkiaSharp, SharpDX.Direct2D 환경에 맞게 쓰시고
개체가 많은 경우 섹터로 나눠야 합니다.
Zoom Out시에는 LOD 적용해서 적당히 빠르게 그려야 하고요

2 Likes