[Flex, ActionScript 3] 최적화된 for와 for each 문 사용법

2008/10/22 20:47
Flex4U 강의(http://cafe.naver.com/flex4u/1091)에 올라온 내용중에 for문에 대한 속도 문제를 거론한 부분이 있어서 직접 테스트해봤다.

다음은 테스트용 코드이다.

package {

        import flash.display.Sprite;

        import flash.utils.getTimer;

 

        /**

         * for, for each 속도 테스트

         * @author : 지돌스타

         * @since : 2008.10.22.

         */

        public class ForTest extends Sprite

        {

               public function ForTest()

               {

                      

                       var arr:Array = new Array(5000000);

                      

                       for( i=0; i < arr.length; i++ )

                       {

                              arr[i] = i;

                       }

                      

                       var i:int;

                       var o:int;

                      

                       var s:Number = flash.utils.getTimer();

                       for( i=0; i < arr.length; i++ )

                       {

                              o = arr[i];

                       }

                       var e1:Number = flash.utils.getTimer() - s;

                      

                       s = flash.utils.getTimer();

                       var length:int;                      

                       for( i=0, length=arr.length; i < length; ++i )

                       {

                              o = arr[i];

                       }

                       var e2:Number = flash.utils.getTimer() - s;

 

                       s = flash.utils.getTimer();

                       var length2:int;                     

                       for( i=0, length2=arr.length; i < length2; i++ )

                       {

                              o = arr[i];

                       }

                       var e3:Number = flash.utils.getTimer() - s;

 

                      

                       s = flash.utils.getTimer();

                       for each( o in arr )

                       {

                              //trace( o );

                       }

                       var e4:Number = flash.utils.getTimer() - s;

 

 

                       trace( "for( i=0; i < arr.length; i++ ) : " + e1 + "ms");

                       trace( "for( i=0, length=arr.length; i < length; ++i ) : " + e2 + "ms");

                       trace( "for( i=0, length2=arr.length; i < length2; i++ ) : " + e3 + "ms");

                       trace( "for each( o in arr )  : " + e4 + "ms");

                      

               }

        }

}

 

 


5000000 건 테스트

for( i=0; i < arr.length; i++ ) : 841ms
for( i=0, length=arr.length; i < length; ++i ) : 492ms
for( i=0, length2=arr.length; i < length2; i++ ) : 503ms
for each( o in arr )  : 132ms


20000000 건 테스트

for( i=0; i < arr.length; i++ ) : 3358ms
for( i=0, length=arr.length; i < length; ++i ) : 1977ms
for( i=0, length2=arr.length; i < length2; i++ ) : 2001ms
for each( o in arr )  : 522ms

결과적으로

1. ++i와 i++는 거의 속도 차이를 못봤습니다.

2. length = arr.length 한것과 안한 것은 확실히 속도차이 납니다.

3. for 문보다는 for each 문이 월등히 빠릅니다.



그러므로 무조건 for each를 써야한다?

그건 아니다. 왜냐하면 인덱싱이 필요한 경우 for each 문에  아래와 같이 쓴다면 오히려 포퍼먼스를 낮추는 결과를 초래한다.


                       i=0;

                       for each( o in arr )

                       {

                              i++;

                       }


그러므로 for를 써야할지 for each를 써야할지 판단해서 선택하는게 좋겠다.


글쓴이 : 지돌스타(http://blog.jidolstar.com/395)

Adobe Flex / ActionScript 3.0 , , , , , , , , ,

  1. 좋은 거 하나 알았네요 ㅋ

  2. 뭘요~~~ 테일러님덕분에 저도 좋은거 알았네요 ㅋ

  3. 언어 수준에서 for each를 지원해주는건 참 좋은것 같습니다^^

  4. 예 일단 쓰기 편하죠 ^^

  5. 와우.. for each 쓰는 습관을 들여야 겠어요. 잘 보았습니다.

  6. Blog Icon
    바람내음

    for( i=0; i < arr.length; i++ ) : 1185ms
    for( i=0,i=0, length=arr.length; i < length; ++i ) : 247ms
    for( i=0, length2=arr.length; i < length2; i++ ) : 251ms
    for each( o in arr )) : 461ms
    for each( o in arr )) {i++} : 497ms
    전 이렇게 나왔습니다. 이거 뭔가 틀린건가요? 테스트는 20,000,000건입니다.

  7. 위에 제 예시대로 하신건가요? 아니면 무엇을 다르게 하셨나요?
    위 코드로 20,000,000건으로 다시 테스트 했는데
    아래와 같은 결과가 나왔습니다.

    for( i=0; i < arr.length; i++ ) : 3206ms
    for( i=0, length=arr.length; i < length; ++i ) : 1851ms
    for( i=0, length2=arr.length; i < length2; i++ ) : 1860ms
    for each( o in arr ) : 585ms

    명확한 비교를 위해서는 for 내부에 arr[i] = i; 등을 빼서는 안됩니다. 그럼 for가 월등이 빨라지겠죠? for each를 사용하는 이유는 arr[i]와 같이 별도의 참조없이 바로 arr 내부에 객체를 하나씩 빼낼 수 있다는 겁니다. 그 부분에서 속도 차이가 있다는 것을 명시한 글입니다.

  8. Blog Icon

    저도 테스트 해봤는데 아래와 같이 나오네요..
    흠 for-each가 느리네요? 사양에 따라 다른건가..
    5백만
    for( i=0; i < arr.length; i++ ) : 295ms
    for( i=0, length=arr.length; i < length; ++i ) : 54ms
    for( i=0, length2=arr.length; i < length2; i++ ) : 54ms
    for each( o in arr ) : 103ms

    2천만
    for( i=0; i < arr.length; i++ ) : 1185ms
    for( i=0, length=arr.length; i < length; ++i ) : 213ms
    for( i=0, length2=arr.length; i < length2; i++ ) : 218ms
    for each( o in arr ) : 410ms

  9. 재미있네요. Flash Player 버전하고 관계가 있을까라는 생각이 듭니다. 정확한 이유는 잘 모르겠네요.

  10. 그게..저 테스트는 사실 아무런 의미가 없어용 ^^
    항상 문제는 실제로 실행중에 복잡한 메모리가 힙에 할당되어 메모리 단편화가 충분히 이루어진 후에나 나타나기 때문입니다.
    어플이 시작하여 아무것도 없는 상태에서 메모리를 할당하면 단순 인덱스 루프를 도는 for가 빨라보입니다.
    하지만 런타임에 복잡한 객체들이 실행되고 메모리가 많이 단편화된 상황으로 가면 for each가 더욱 유리해집니다.
    참고로 for in 은 항상 느린 편인데 약간 개선하기 위해서는
    for( var key:* in ..처림 key를 *를 줘서 내부적인 형변환을 제거하면 성능개선이 많이 됩니다.
    이것도 역시 상세하게 ggpro님의 포스트가 있습니다.
    http://blog.naver.com/ggpro/30068781458

  11. 그렇군요!

    링크드리스트와 몇가지 최적화된 연산자 사용으로 저렇게 빨라지는 것을 보면... 대단하군요. 바이트 코드를 보면서 루프의 최적화를 설명하신 이분 설명이 명쾌하네요. 저런식의 접근은 예전에 마이크로프로세서를 다루면서 어셈블러를 약간 다룰때 말고는 기억이 가물가물...

  12. Blog Icon
    Sait2000

    for..in문이 for each..in문보다 빠른 것 같은데요?

  13. 너무신기해용