|
말씀하신 코드로는 총 시간이 AnsiString의 생성자 시간에 크게 영향을 받을 수 있을 거 같아
제대로된 측정이 불가능 한 것 같습니다. 결과를 봐도, 매번 결과가 다르게 나오네요.
또한, 윈도우 환경에서는 각 Thread에 배정되는 실행시간이 항상 바뀌므로
정확한 시간을 측정하기에 무리가 있습니다.
직접 측정을 해보셔도 매번 순서가 바뀌는 걸 확인할 수 있으실 겁니다.
원칙적인 입장에서 설명을 드리자면,
++i > (--i , i++) > i--
의 순서로 속도 차이가 날 것입니다.
++이나 --을 prefix로 쓸 때와, postfix로 쓸 때의 차이점은
임시변수 하나를 더 생성해 주어야 하느냐의 차이입니다.
prefix로 사용할 경우, ++i의 return 값은 ++ 수행 후의 i 값과 동일합니다. 따라서 리턴을 위한 int형 임시변수 하나만 있으면 되지요.
하지만 postfix로 사용할 경우, i++의 return 값은 ++ 수행 후의 i값과는 차이가 있습니다. 따라서 리턴을 위한 임시변수 외에도, 기존 i값을 담아두기 위한 임시변수 하나가 더 필요합니다.
즉,
prefix 의 시간 : ++ 수행, 임시변수 생성
postfix 의 시간 : ++ 수행, 임시변수 생성*2개
--도 마찬가지 입니다.
prefix 의 시간 : -- 수행, 임시변수 생성
postfix 의 시간 : -- 수행, 임시변수 생성*2개
++와 --의 차이는 더하기와 빼기의 차이이지요.
컴퓨터에서 빼기 연산은 더하기와 알고리즘은 같되, 더하기 전에 보수를 구해서 더한다는 거 아시죠?
++은 1을 그냥 더해주면 되지만, --는 1의 보수를 구해서 더해줘야 합니다.
그래서 --는 보수를 구하는 시간이 추가되겠지요.
++ 수행의 시간 : 더하기 수행
-- 수행의 시간 : 보수 구하기 + 더하기 수행
p.s.
++, -- 수행 시간의 차이는 CPU의 최적화 방법에 따라 다를 수 있습니다.
1의 보수는 항상 (11111111 in 2진수, 8바이트값이라고 했을때) 로 정해져 있으므로,
--를 수행할 때마다 보수를 구하지 않고, 미리 계산된 1의 보수값을 더해주면 되기 때문이지요.
라스코니 님이 쓰신 글 :
: 일반적인 데스크탑 환경에서는 별의미가 없겠으나 코드의 성능에 민감한 임베디드 쪽에서는 고려할 만도 한 내용이네요.
:
: i-- 와 i++ 중 어떤 것이 더 빠르냐 하는 것이네요?
:
: 저는 테스트해보지는 않았지만 추측건대 차이가 없다는 쪽으로 생각이 드네요. 왜냐하면 프로세서의 연산기를 설계할 때 덧셈 연산기와 뺄셈 연산기를 성능이 차이나도록 설계하지 않았을 거구요. 덧셈, 뺄셈, 논리 연산은 프로세서의 가장 기본적인 연산이므로 그만큼 성능이 차이가 날만큼 복잡한 기술도 들어가지 않았을 거라는 추측입니다.
:
: 하지만 i--와 i++을 for 루프에서 어떻게 사용하느냐에 따라서 조금 성능차이는 있다고 합니다.
:
: 예를 들어
:
: for ( i = 1 ; i <= 100 ; i++ )
: sum += i;
:
: 보다는
:
: for ( i = 100 ; i-- ; )
: sum += i;
:
: 가 더 빠르답니다.
:
:
:
:
: 허정주 님이 쓰신 글 :
: : 네 로직은 열심히 신경쓰는데
: : 그냥 궁금해져서 질문한거에요.
: : 정말 궁금해요.
: :
: : zi 님이 쓰신 글 :
: : : 이런거 신경쓰지 마시고 로직에 신경을 쓰는게... ^^
: : : cpu 가 하루가 다르게 발전하고 있는데... 별 의미 없어보이네요..
: : : 특히 i++, ++i 는 구분은 특별히 구분해서 써야 할 때가 있지만 쓰임은 속도가 아니라 로직상 구분해서 쓰는 거에요.
: : : 일반적으로는 거의 구분없이 쓰여질때가 많습니다.
: : :
: : : 허정주 님이 쓰신 글 :
: : : : 연산자가 전치/후치에 따라 빠르기 순서가 다음과 같았습니다.
: : : :
: : : : i-- > i++ > ++i > --i
: : : :
: : : : 전 마지막 것이 빠른줄 알고 썼었는데 ㅡㅜ
: : : : 왜 이런지 아시나요;;
: : : :
: : : :
: : : : 아래는 테스트에 사용 된 코드였습니다.
: : : : void __fastcall TForm1::Button1Click(TObject *Sender)
: : : : {
: : : : unsigned int Before;
: : : : double t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0;
: : : : double loop = 10;
: : : : for ( int i = 0; i < loop; ++i )
: : : : {
: : : : Before = GetTickCount();
: : : : for ( int i = 0; i < 1000000; ++i )
: : : : {
: : : : AnsiString s = AnsiString( "s" );
: : : : }
: : : : t2 += ( GetTickCount() - Before );
: : : :
: : : : Before = GetTickCount();
: : : : for ( int i = 0; i < 1000000; i++ )
: : : : {
: : : : AnsiString s = AnsiString( "s" );
: : : : }
: : : : t3 += ( GetTickCount() - Before );
: : : :
: : : : Before = GetTickCount();
: : : : for ( int i = 1000000; i > 0; --i )
: : : : {
: : : : AnsiString s = AnsiString( "s" );
: : : : }
: : : : t4 += ( GetTickCount() - Before );
: : : :
: : : : Before = GetTickCount();
: : : : for ( int i = 1000000; i > 0; i-- )
: : : : {
: : : : AnsiString s = AnsiString( "s" );
: : : : }
: : : : t5 += ( GetTickCount() - Before );
: : : : }
: : : : Memo1->Lines->Add( FloatToStr( t1 / loop ) );
: : : : Memo1->Lines->Add( FloatToStr( t2 / loop ) );
: : : : Memo1->Lines->Add( FloatToStr( t3 / loop ) );
: : : : Memo1->Lines->Add( FloatToStr( t4 / loop ) );
: : : : Memo1->Lines->Add( FloatToStr( t5 / loop ) );
: : : : }
|