1 Results for '성능 문제'

  1. 2007.07.17 [Silverlight] TextBlock의 성능 문제 (8)
동기식 비동기식 무엇이 다르단 말인가? 에서 트랙백.
관련 스레드로, 네이버 실버라이트 카페도 참고.
 
TextBlock의 성능 문제

아주 심플하게 제목이 결론이에요.

좀 더 구체적으로 얘기하자면 다량의 메모리와 렌더링을 요구하는 오브젝트를 실버라이트 페이지의 루트 캔버스에 추가(Children.Add)했을 때 이 오브젝트를 렌더링하기 위한 시간이 상당히 길고 이 시간 동안 실버라잇 런타임이 프리징 되는 문제. 라고 할 수 있겠네요.

먼저 이 상황을 시뮬레이션 하는 예제를 먼저 돌려 보세요.
http://gongdo.oranc.co.kr/Silverlight/Samples/TextBlockPerformanceIssue/TestPage.html


샘플 프로젝트는 아래에서 다운로드.
TextBlockPerformanceIssue.zip

TextBlock 성능 문제 샘플 프로젝트


아래는 시뮬레이션의 예제에요.



각 버튼들의 이벤트 핸들러에는 10, 100, 1000, 5000, 10000, 50000 라인의 텍스트를 동적으로 생성하여 TextBlock으로 추가하는 코드가 작성되어 있어요. 그리고 코드의 각 진행 단계마다 진행 시간을 밀리세컨드 단위까지 표시하고 있고요.

이때 1000라인 까지는 아무런 문제 없이 부드럽게 진행되다가 5000라인쯤 되면 뭔가 답답하게 올라오고 10000라인쯤 되면 눈에 띄는 성능저하가 일어나며 50000라인쯤 되면 단순히 빙글빙글 돌아가는 애니메이션이 느려질 정도로 급격한 성능저하가 일어나요.

어디에서 문제가 일어나는가?
로그를 잘 보면 문자열을 1000라인이든 50000라인이든 작성하는 것 자체는 시간이 전혀 안 걸려요. 그리고 TextBlock을 코드-비하인드에서 동적으로 생성하거나 긴 문자열을 Text 속성에 설정하거나 하는 행위까지도 시간이 거의 안 걸리죠. 그런데, 이 TextBlock을 루트 캔버스의 Children에 추가하는 순간 라인이 길 수록 부하가 대폭 증가하는 것을 볼 수 있어요. 정확하지는 않지만, 아마 선형으로 증가할 거라고 예상해요.

왜 느려지는가?
이 부분은 전적으로 제 추측일 뿐이에요. 아직 공식적인 답변이나 의견은 얻지 못했으니 감안하고 봐주세요.
그렇다면 TextBlock 개체를 실버라이트 페이지의 개체 트리에 추가하는 순간에 문제가 생길 거라고 성급하게 예측할 수 있지만, 사실 이 시간 역시 그리 오래 걸리지 않는다고 봐요. 개체가 추가되기 위해 시간이 걸리는 게 아니라 개체를 렌더링, 화면에 뿌리기 위한 오버헤드가 크다는 것을 알 수 있어요.

어떻게 알았냐? 바로 5만 라인쯤 추가하면 아무것도 안 해도 옆에서 돌고 있는 애니메이션까지 느려지기 때문이죠. 그 얘기는 애니메이션을 렌더링 할 때 TextBlock 역시 새로 렌더링 될 텐데, 이 때 이 TextBlock을 렌더링 하는 시간이 오래 걸리기 때문에 애니메이션 까지 느려지는 거죠.

그렇다면 왜 느려질까요?
다시 한번 강조하지만 어디까지나 제 추측이에요.

제 예상으로는 TextBlock의 컨텐츠(여기에서는 Text 속성)을 렌더링 할 때 조금 똑똑한 런타임이라면 한번은 모든 Text를 렌더링 하겠지만 Text가 바뀌거나 어떤 변형이 가해지지 않은 이상 렌더링 된 결과 스냅샷을 메모리에 저장해놨다가 다음 렌더링 요청때 해당 스냅샷을 사용하여 화면에 뿌리고 또한 화면에 표시되지 않는 영역에 대한 렌더링은 하지 않는 클리핑 동작을 할거에요.

그런데, 이렇게 까지 일정하게 느려진다는 것은 위의 두 가지 동작중 적어도 하나는 하고 있지 않다는 얘기가 돼요. 말하자면 렌더링 요청이 있을 때마다 모든 Text 내용을 렌더링 하느라 느려지거나 렌더링 하지 않아도 될 영역까지 렌더링 하느라 느려지거나 최악의 경우 이 두 가지 짓을 다 할 수 있다는 거죠.

남은 건 절망 뿐인가~ 예~예에~♬
물론 그렇진 않죠.
이것은 비공식 채널에서 얼핏 스쳐 본 내용이라 잘못 본 걸 수도 있지만, 실버라잇 베타, 알파의 많은 엘리먼트나 코드들이 디버그 코드라고 해요. 그래서 릴리즈되면 자연히 해결된 문제도 많다는 거죠.

그리고 실버라잇에서 String의 할당 성능 문제 등의 자잘한 성능 이슈는 이미 Silverlight.net의 포럼에서 많이 지적되고 있는 문제에요. 이걸 그냥 넘어가진 않을거라고 생각해요.

그리고 더 중요한 것.
애초에 만 라인, 오만 라인씩이나 뿌리는 페이지를 기획 한 것부터가 문제라는 거에요!

아니 애시 당초 사람이 웹 페이지에서 이런 대용량의 데이터를 한눈에 볼 수 있을 리가 없잖아요?
요즘처럼 AJAX다 뭐다 페이지의 리프레쉬 없이도 데이터를 연속적으로 표시할 수 있는 수단이 얼마든지 있는데 무조건 꾸겨 넣으려는 그 생각이 문제라고요!

이건 성능테스트를 하다가 흔히 빠질 수 있는 함정인데요, 저도 처음에 이 문제 테스트를 위해 10, 100, 1000라인으로 테스트했어요. 그러다가 그 정도로는 별 부하가 안 걸리길래 막 늘렸죠 5000, 10000, 50000... 그러다가 만 라인쯤 되어서 부하가 막 걸리니까 '어? 이거 왜 그래? 뭐가 불만이야? 엉? 엉? 엉?' 이런 생각이 들었어요.

그렇지만, 현실적으로 이 정도 데이터를 표시하는 거라면 애초에 다른 수단을 쓰던가 아니면 비동기적인 페이징 기법을 사용했어야 한다는 게 정답이죠.

성능 테스트의 의욕은 높이 살 만 하지만, 눈앞의 성능 테스트에만 집착하다가 내가 왜 이 테스트를 하게 되었는지를 잊어버리면 안 된다는 거에요.

오우~ 실버라잇 만세?
물론 그렇진 않죠.
아까 얘기한 것처럼 분명히 렌더링 과정에서의 문제점은 있을 걸로 예상해요. 이것이 디버그 코드이기 때문에 그런지는 아직 모르겠지만 여하튼 위 예제에서의 TextBlock과 같이 커다란 메모리를 가지는 개체를 렌더링 할 때에도 같은 현상이 일어나요.

때문에 이런 성능 상의 문제는 차기 버전에서 반드시 개선되어야 할 사항이라고 생각해요.


결론
저야 일개 개발자로 무슨 힘이 있겠습니까. 그저 잘 되길 바랄 뿐이죠. 그런 점은 좀 아쉽네요.
한국 MS에도 개발 전도사를 뽑는다고 하는데 인선이 되면 무시무시하게 달려들 수도 있겠죠.

아, 사건 의뢰의 구체적인 답을 정리하지 않았군요.

낙훈님이 얘기한 문제는 동기/비동기 방식이 차이가 없는 게 아니라 데이터를 수신 받은 이후의 처리 과정이 동일했고 그 과정이 오래 걸리기 때문에 결과가 같아 보였을 뿐이라는 거에요.

그리고 그 원인은 위에서 설명한 대량의 렌더링이 필요한 개체를 루트 캔버스에 올렸을 때 발생하는 성능 저하에 있고요.
-끝-
Posted by gongdo

Submit comment.

  1. Favicon of http://blog.naver.com/super810910 BlogIcon 슈퍼낙훈 2007.07.17 02:08  comment URL  Edit/Remove  Submit comment.

    역시 그냥 넘어가시지는 않는군요.....
    자세한 답변 정말 감사합니다!

    갑자기 제가 예전에 썼던 글이 떠올라서 긁어다 보면요
    --------------------------------------------------------------------------
    플렉스 데이타 서비스로 데이타를 땡겨왔을때 1000건 정도 까지라면 ajax와 다를바 없지만
    만건이던 10만건이던 1초 정도에서 해결되더라구요
    그거 말고는 플렉스의 그렇다할 강점을 크게 드러내지는 못했는데요
    전 개발자가 된지 얼마 안돼서 잘 모르겠는데요
    웹에서 왜 10만건을 땡겨와야하죠?
    제가 잘 몰라서 그렇다고 치더라도 사실 웹에서 1000건 이상의 데이타를 불러와야할 일이 얼마나 자주 있다고 그러는건지 잘 이해가 안됐습니다.
    --------------------------------------------------------------------------

    라고 제가 떠들었으면서....푸헹....


    이번건 말고라도 '아 맞다! 아 맞다!' 그럴때가 많아요.

    항상 기술적인것 말고라도 많이 배우는것 같아요.

    NEXT 스테얼츠 기다리겠습니다! 쭝썽!

    • Favicon of https://gongdosoft.com BlogIcon gongdo 2007.07.17 02:22 신고  comment URL  Modify/Remove

      아... 정작 중요한 얘긴 빼먹었네-_-;
      그러니까 데이터 양이 동일할 경우 동기/비동기의 처리 속도의 차이는 오히려 동기쪽이 빠를 수 있지만, 데이터 요청과 응답시 네트워크 상의 지연이 걸리는 상황에서는 비동기쪽 처리가 훨씬 유연하다는 거죠.^^

  2. Favicon of http://blog.naver.com/super810910 BlogIcon 슈퍼낙훈 2007.07.17 02:31  comment URL  Edit/Remove  Submit comment.

    넵! 숙지하겠습니다!!!

  3. 네오군 2007.07.17 10:12  comment URL  Edit/Remove  Submit comment.

    아하하하하하하하~~~~~~~~~~~~

    저는 처음에 예제를 제대로 파악하지 못해서 놀랬습니다.

    예제 나왔을때 무심코 그냥 마우스 클릭 딱 했는데 모르고 5만 줄 라인에 클릭했나바여..

    그런데 실제로 화면에 나오는건 몇줄 안되잖아여..

    그런데 그게 실제로 텍스트블록을 5만개나 띄우는지 모르고 빨간색 네모가 도는게 느려지길래...

    뭐야...??? 이정도로 느리단 말야???????? 아니 이걸 어따 써먹어..

    이랬는데... 좀 더 읽어보니까...

    아니군여...

    저는 오히려... 공도님 생각과 반대입니다...

    기대 이상인데요...

    설마 만줄이나 되도 끄떡 없다니...??

    실제로 과연 한 화면에 500줄이상 ..아니 100줄이나

    뿌리는 상황이 올까 모르겠네요...

    그러므로 안심입니다만.. 괜히 플렉스가.. 10만줄에도 끄떡 없다고 하니... 좀 그러네여 ㅋㅋ;;

    왜 자꾸 플렉스랑 비교가 되는거지 ㅋ

    • Favicon of http://gongdo.tistory.com BlogIcon 공도 2007.07.17 10:30  comment URL  Modify/Remove

      아니 그러니까;;;
      화면에 뭐 만줄 몇만줄 표시하는건 눈꼽만큼도 고려할만한 대상이 아니라는거에요.
      애초에 그런 무식한 서비스를 기획한게 문제이지 화면에 몇 만줄 표시하네 못하네 이게 중요한게 아니라는거죠.
      그리고 플렉스쪽에서 말하는건 데이터를 가져오는 속도를 얘기하는거에요. 본문을 좀 더 자세히 읽어보시면 알 수 있지만 실버라잇도 string 메모리 상에서 처리할 때에는 시간 거의 안걸려요. 문제는 이걸 렌더링 할 때 오래 걸리는 건데, 몇 만줄 정도 되면 HTML조차도 느려지니까 얘기 했듯이 고려할 만한 상황이 아니라는거죠.

  4. 네오군 2007.07.17 10:38  comment URL  Edit/Remove  Submit comment.

    아... 코드를 보니까.. 텍스트블록을 더 띄우는게 아니라 라인.. 그러니까 글자수를 늘리는거군여..

    반대로 텍스트 블록 1개당 1라인으로 하면 엄청난 부하가 걸리겠네여..

  5. 네오군 2007.07.17 10:45  comment URL  Edit/Remove  Submit comment.

    1라인당 텍스트블록을 한개씩 띄우는걸 한번 실제로 테스트 해봐야 겠네요..

    왜냐하면 실제로 게시판 같은걸 구현할때 한 텍스트 박스안에 모든 아이템을 다 구겨넣진 않으니까요..