2011-11-23 2 views
0

제 경우에는 2D ArrayList에 가로선, 세로선 및 채워진 사각형을 그릴 때 사용되는 데이터가있는 객체로 가득차 있습니다. 다른 경우 개체의 양이 다르며 이미지의 선과 직사각형의 양이 다릅니다. 그러나 때때로 이미지를 다시 그려야합니다. 다시 그리는 것이 더 많을수록 화면의 깜박임이 강해집니다 ("깜박임"으로 무엇을 의미하는지 파악할 수 있기를 바랍니다).C#, WinForms 그리기 데이터가 ArrayList에 저장됩니다. 좋은 생각입니까?

나는 이중 버퍼링을 이미 시도해 왔지만, 내가 제대로하고 있다고 생각하지 않는다. 깜박임의 유형 만 변경된다 ... 그러나 그것은 현재의 경우가 아니다.

어디에서나 ArrayList의 요소를 추가하고 제거하는 것은 쉽지만 그 접근은 어렵다는 것을 읽었습니다. List가 더 잘 수행된다는 사실을 읽었습니다. ArrayList는 컴퓨터에서 리소스를 덜 필요로한다는 것을 의미합니다.하지만 끝에서 요소를 추가하고 제거하는 것은 쉽습니다. 그러나 Array의 성능이 가장 빠른지 확실하지 않습니다. 그리고 이것은 Array 나 List로 ArrayList를 변경하면 플래시가 약해질 수 있다고 생각하게 만듭니다.

ArrayList에 저장하는 모든 요소가 같은 클래스의 양식이므로 문제가되지 않습니다.

제 질문은 : ArrayList를 Array 또는 List로 대체하면 깜박임을 약화시킬 수 있습니까?

답변

1

두 가지 문제가 있습니다. ArrayList와 List 질문은 성능의 차이가 작기 때문에 "깜박임"에 영향을 미치지 않습니다. 목록 항목이 모두 같은 유형이거나 모두 object이 아닌 공통 기본 유형에서 파생되었거나 모두 공통 인터페이스를 구현하는 경우 List<T>이 더 나은 선택입니다. 이것은 주물이 적기 때문이며 boxing/unboxing이 포함되기도합니다. 또한 항목에 쉽게 액세스 할 수 있습니다.

깜박임 : 모든 그림을 (사용자의 양식 또는 제어 도구의) 페인트 이벤트 메소드로 수행하십시오. 그런 다음이 양식이나 컨트롤의 Invalidate 메서드를 호출하십시오. "직접"그리지 마라. 개선 사항으로 사각형 구조를 전달하여 무효화하고 어떤 부분을 다시 그려야 하는지를 알릴 수 있습니다. 페인트 메소드에서, 당신은 e.ClipRectangle을 체크 할 수있다. 이것은 어떤 부분을 다시 그려야하는지 알려준다. 이것은 당신에게 여기에 약간의 개선을 할 수있는 기회를 제공합니다. 그러나 Windows OS 자체가 임의의 ClipRectangles를 발생시키는 Invalidate를 트리거 할 수 있다는 사실을 알고 있어야합니다.

0

"깜박임"을 수정하려면 이중 버퍼링을 활성화해야합니다.

실수 나 잘못된 디자인을 유발할 수 있으므로 ArrayList를 사용하면 안됩니다.
여러 유형의 개체가 포함 된 목록이 있어서는 안됩니다.

대신 다형 기본 클래스를 사용하여 List<T>을 사용해야합니다.

1

그리기 성능과 ArrayList 성능을 비교하면 다른 데이터 컨테이너를 사용하여 깜박임 문제를 해결할 수 없습니다. 따라서, ArrayList의 대체 컨테이너가 답이 아닙니다. 다른 방법을 사용해야합니다. 그래픽 라이브러리와 같은 SDL, DirectX, OpenGL를 사용

  • .
  • 비트 맵 버퍼에 그리기 및 비트 맵 완료 후 표시 (더블 버퍼링과 유사하지만 때로는 더 잘 작동 함).
  • 일부 구성 요소를 서브 클래스로 만들고 배경 그림과 같은 일부 메서드를 재정의합니다.

더 많은 방법이 있지만 질문에 대한 대답은 확실히 ArrayList와 관련이 없습니다.

+0

경우에 따라 물체의 양은 2x2 또는 4x3이지만 10x10 이상입니다. (NxM에서는 M 요소가있는 N 개의 배열을 의미합니다.) 그리고 사각형에는 그리기에 더 많은 시간이 필요합니다. "깜박임을 약화"한다는 것은 "깜박임을 멈추는 것"을 의미하지는 않았지만 나는 그림을 더 빠르게 만드는 방법을 의미했습니다. 그리고 네, 문제를 해결하기 위해 이중 버퍼링을해야한다는 것을 알고 있습니다. 그러나 드로잉을 더 빠르게 만들면 (더블 버퍼링이 더 빨라질 것입니다.), 앱도 더 빨라질 것입니다. 그리고 그것은 "할 일"목록에 속하는 것 중 하나입니다. – AlexSavAlexandrov

+0

필자는 항상 최적화 된 코드를 작성하는 것을 지원했지만, 성능 변화는 눈에 띄게 또는 아닙니다. 하지만 귀하의 경우 1000x1000 반복으로 약 10-50 밀리 초가 소요됩니다. 10-50 밀리 초와 비교하여 1000000 개의 직사각형을 그리는 데 얼마나 오래 걸릴지 생각하십시오. (여기를보십시오 : http://www.dotnetperls.com/unboxing). int 유형에 대한 이러한 결과는 다른 유형의 경우 최대 5 배 가량 소요될 수 있으며 반복 횟수를 100 배 줄였다 고 가정했습니다. 그래서, 우리 모두는 1000000 개의 직사각형 그리기와 유사한 객체가 많은 시간을 소비한다는 것을 알고 있습니다. IMHO, 성능 향상은 % 0.1보다 크게 높지는 않습니다. –

1

ArrayList 대신 List<T>을 사용해야합니다. 목록에서 개체를 읽을 때 불필요한 캐스팅을 제거하기 만하면됩니다. 그러나 그로 인한 성능 향상은 그리기 그래픽에 비해 너무 적어서 업데이트 문제에 눈에 띄는 영향을 미치지 않습니다.

그래픽을 비트 맵으로 그리는 것을 고려한 다음 화면을 업데이트해야 할 때 비트 맵을 그릴 수 있습니다.


List<T>

하고 요소 추가 및 제거에 올 때 ArrayList 동일한 동작; 목록 끝에 요소를 추가하거나 제거하는 것은 저렴하지만 목록 시작 부분에 요소를 삽입하거나 제거하는 것이 더 비쌉니다.

배열이 가장 빠른 목록이며 List<T>ArrayList은 배열을 사용하여 요소를 내부적으로 저장합니다. 그러나 배열의 크기를 조정할 수 없으므로 필요에 따라 배열을 할당하는 작업을 수행하고 배열의 사용량을 추적하므로 배열을 List<T>으로 계속 사용할 수 있습니다.

+0

'List '은 값 유형에 비해 훨씬 빠릅니다. – SLaks

관련 문제