한2년전에 테스트했던 내용이 있길래 올려둡니다.
1. 문자열내에 변수파싱 속도
2. 함수인자로 값과 레퍼런스를 넘길때 속도
3. 함수 리턴값을 값과 레퍼런스로 넘길때 속도
공통사항
1. 변수는 {'str'.$i} 와 같은 형태로 계속 다른 변수명을 지정합니다.
2. 변수내용에는 $i 를 삽입하여 다른 문자열을 생성
3. 배열의 경우에도 $i 만큼 변동되는 배열생성
4. unset 함수로 변수파기(메모리땜에 ㅠㅡㅠ)
5. 모든 단위는 초
6. 3회 측정후 시간차가 1초이상 벌어질경우 재측정한후 유사값을 기재.
참고 : 1,2,3 항의 경우 같은 변수명에 같은 내용의 문자열을 반복적으로 할당할 시 캐시와 같은 기능이 동작될 수 있으므로 최대한 변수명과 문자열의 내용을 계속 변경하며 할당하는 방식을 사용합니다.
1. 변수 파싱 테스트---------------------------------------------------------------------
$msg = "message";
$msg1 = "asfdasdf";
$msg2 = "aszxvzxvzxvc";
$msg3 = "asdfasfdasdfasfasdf";
$msg4 = "가나다라마바사아자차카타파하";
for ($i=0; $i<5000000; $i++) {
${"str".$i} = "{$msg} {$msg1} {$i} {$msg2} {$msg3} {$msg4}";
unset(${"str".$i});
}
"{변수}"
31.45102
31.430929
"".변수.""
24.74499
24.732148
''.변수.''
24.773771
24.704646
결론 " 와 ' 의 차이점은 없다. 단 {} 의 경우 속도가 느리다.
사실 " 와 ' 의 차이를 알기위해 한 실험인데 {} 의 속도만 느린걸로 결론이 났습니다.
하지만 변수파싱 유무의 경우 변수길이가 늘어나면 더 차이가 날것으로 판단
좀더 긴 문자열로 다시 테스트를 합니다.
1-1. 큰 변수 파싱 테스트----------------------------------------------------------------
문자길이 strlen = 2379 길어서 올리긴 그렇군요.
테스트1과 같이 가변변수명에 문자열내에 계속 변경되는 $i를 포함하여 다른 문자열을 할당하도록 합니다.
참고 : 문자열이 긴데도 처리속도가 테스트1과 비슷하게 나온건 반복횟수를 줄여서입니다. 시간이 너무 걸리더군요.
결과
"{변수}"
25.127708
25.137791
"".변수.""
34.942367
34.920367
''.변수.''
34.936865
34.950143
의외의 결과가 나왔습니다.
{} 의 경우 짧은 문자열일경우 속도가 느리지만 긴문자열의 경우에는
속도차가 엄청나게 나는군요. ㅡㅡ;;
역시나 " 와 ' 의 차이는 거의 없다고 결론
2. 함수인자로 값과 레퍼런스를 넘길때 속도 ------------------------------------
function test($arr) {
return $arr;
}
for ($i=0; $i<10000; $i++) {
${'arr'.$i} = array_pad(array(), $i, 0);
${'res'.$i} = test(${'arr'.$i});
unset(${'arr'.$i},${'res'.$i});
}
값 ($arr)
11.083365
10.926317
참조 (&$arr)
20.715445
20.365709
결과 레퍼런스 전송이 엄청나게 느리군요. ㅡㅡ;;
그럼 $arr 의 값이 함수내에서 변경이 되면 어떨지 다시 실험
test 함수를 아래와 같이 변경.
function test($arr) {
array_push($arr,111);
return $arr;
}
값 ($arr)
36.02203
36.187773
참조 (&$arr)
20.510085
20.508372
전달받은 값이 함수내에서 변경될경우 확실히 레퍼런스가 속도가 빠르네요.
참조를 사용하면 굳이 함수내에서 리턴해줄 필요가 없다고 보고
참조 부분을 아래와 같이 변경합니다.
function test(&$arr) {
array_push($arr,111);
}
//
test(${'arr'.$i})
${'res'.$i} = ${'arr'.$i};
실제라면 참조를 이렇게 사용하겠죠.
결과
20.730086
20.862306
역시 전달받은 값이 변경이 되면 참조가 빠르다는 결론이 났습니다.
함수에 값을 전달하면 값의 내용에 변화가 없을경우
값 복사가 아니라 참조전송과 같은 형태가 되는것으로 보입니다.
일반적으로 사용은 전달 값을 변경하는것 보다는
전달한 값으로 다른 값을 만들어 리턴하는 방식을 많이 쓰니
참조 전달은 피해야 할것 같군요.
3. 함수 리턴값을 값과 레퍼런스로 넘길때 속도 --------------------------------------
보통 함수를 사용할때는 참조를 리턴하지 않겠죠. 스택에 생성된 값이 파괴되버리니
하지만 PEAR MDB2 에 query,fetchRow 와 같이 참조를 리턴하는 함수를 위해
테스트를 합니다.
위 함수에서
값리턴
function test($arr) {
static $tmp;
$tmp = $arr;
array_push($tmp,111);
return $tmp;
}
참조리턴
function &test() { ...}
${'res'.$i} =& test(${'arr'.$i});
와 같이 static 변수를 만들어 스택에서 파괴되지 않도록 하고 리턴을 합니다.
값을 변경해줘야지 정확하게 리턴값을 테스트할수 있겠네요.
결과
값리턴l
66.687707
69.361783
참조리턴
47.410089
47.472425
참조리턴이 더 빠른것으로 나옵니다.
리턴될 값이 작을경우는 테스트 못해봤네요.
결론 ----------------------------------------------------------------------------------
1. "" 와 '' 의 처리속도는 매우 근소하여 오차범위 내에 있음으로 '' 만 고집하기 보다는 상황에 맞게 사용해야 한다.
2. 짧은 문자열의 경우 "{변수}" 보다는 연결자(.) 을 이용한 ".변수." 또는 '.변수.' 와 같은 형식이 빠르다.
3. 긴 문자열의 경우 "{변수}" 의 처리속도가 빠르다.
4. PHP5 의 경우 대입문(=),함수인자,함수리턴시 기본적으로 참조로 동작을 하게되고 값이 변경되는 경우에 별도의 변수를 할당하는 것으로 동작합니다. 그렇기 때문에 5와 같은 결과가 나타납니다.
5. 함수 인자 전송과 리턴값 전송시 값의 내용이 중간에 변경되면 참조방식이 변경되지 않으면 값전달 방식이 효과적입니다.
$a = 1; // 새로 할당
$b = $a; // 일단 참조
$b = 2; // 이때 새로 할당
test($b); // 일단 참조
function test($c)
{
$c = 4; // 이때 새로 할당
}
6. 참고로 함수관련 전달 인자들을 배열로 한부분이 조금 문제가 될수 있겠군요. PHP가 기본적으로 C 로 구성되어 있는데 C에서 배열의 인자전송등은 포인터로 이루어지니 테스트에서 의도한 바와는 조금 다르게 결과가 나왔을 수도 있을 것 같네요. 함수의 인자를 문자열로 변경하여 다시 테스트해봐야 겠습니다.