PHP FOR에서 FOREACH의 성능
PHPPHP FOR에서 FOREACH의 성능
우선, 90 %의 응용 프로그램에서 성능 차이가 전혀 관련이 없다는 것을 알고 있지만, 더 빠른 구조가 무엇인지 알아야합니다. 그것과 ...
그물에 그 (것)들에 현재 유효한 정보는 복잡합니다. 많은 사람들은 foreach가 좋지 않다고 말하지만 기술적으로는 반복자를 사용하여 배열 순회를 단순화한다고 가정하기 때문에 기술적으로 더 빨라야합니다. 반복자는 다시 빠르지 만 PHP에서는 죽은 것처럼 느껴진다 (또는 PHP가 아닌가?). 나는 배열 함수에 대해 말하고있다 : next () prev () reset () 등등. 함수가 짝수이고 함수처럼 보이는 PHP 언어 기능 중 하나가 아니라면 말이다.
이 점을 조금 좁히려면 : 1 이상의 단계로 배열을 순회하는 것은 흥미롭지 않습니다 (부정적인 단계도 없기 때문에 역순으로 반복합니다). 나는 또한 임의의 점을 통과하는 데 관심이 없으며 길이는 0에 불과하다. 나는 또한 1000 개 이상의 키가 정기적으로 발생하는 배열을 조작하는 것을 보지 못했지만 배열 논리가 응용 프로그램의 논리에서 여러 번 통과하는 것을 보았습니다! 또한 조작의 경우에는 주로 문자열 조작 및 반향 만합니다.
다음은 참조 사이트가 거의없는 경우입니다. http://www.phpbench.com/ http://www.php.lt/benchmark/phpbench.php
내가 들려주는 모든 것 :
여기 내 문제가있다. 나는이 테스트 스크립트를 작성했다 : http://pastebin.com/1ZgK07US 그리고 내가 스크립트를 몇 번이나 실행했는지 상관없이 나는 다음과 같은 것을 얻는다.
foreach 1.1438131332397
foreach (using reference) 1.2919359207153
for 1.4262869358063
foreach (hash table) 1.5696921348572
for (hash table) 2.4778981208801
간단히 말해서 :
누군가 설명 할 수 있습니까?
PHP 버전 5.3.0 편집 : 답변 여기에있는 사람들의 도움으로 나는 모든 질문에 대한 해답을 모을 수있었습니다. 여기서 요약 해 보겠습니다.
도와 주신 모든 분들께 감사드립니다.
모든 간단한 탐색을 위해 foreach (참조가 아닌 버전)를 사용합니다.
해결법
-
==============================
1.나의 개인 의견은 맥락에서 의미가있는 것을 사용하는 것이다. 개인적으로 나는 배열 탐색을 위해 거의 사용하지 않는다. 다른 유형의 반복에도 사용하지만 foreach는 너무 쉽습니다 ... 대부분의 경우 시간 차이는 최소화 될 것입니다.
나의 개인 의견은 맥락에서 의미가있는 것을 사용하는 것이다. 개인적으로 나는 배열 탐색을 위해 거의 사용하지 않는다. 다른 유형의 반복에도 사용하지만 foreach는 너무 쉽습니다 ... 대부분의 경우 시간 차이는 최소화 될 것입니다.
감시해야 할 가장 중요한 사항은 다음과 같습니다.
for ($i = 0; $i < count($array); $i++) {
매 반복마다 카운트를하기 때문에 값 비싼 루프입니다. 네가 그렇게하지 않는 한, 나는 그것이 정말로 중요하다고 생각하지 않는다.
차이점을 만드는 참조에 관해서 PHP는 copy-on-write를 사용하므로 배열에 쓰지 않는다면 루핑하는 동안 오버 헤드가 상대적으로 적을 것입니다. 그러나 배열 내에서 배열을 수정하기 시작하면 각 배열 사이에 차이점이 표시되기 시작합니다 (전체 배열을 복사해야하므로 참조가 인라인으로 수정 될 수 있음).
이터레이터의 경우 foreach는 다음과 같습니다.
$it->rewind(); while ($it->valid()) { $key = $it->key(); // If using the $key => $value syntax $value = $it->current(); // Contents of loop in here $it->next(); }
반복 할 수있는 더 빠른 방법이있는 한 문제는 실제로 문제에 달려 있습니다. 그러나 나는 정말로 물을 필요가있다, 왜? 보다 효율적인 작업을 원한다는 것을 이해하지만 마이크로 최적화에 시간을 낭비하고 있다고 생각합니다. 조기 최적화는 모든 악의 근원임을 기억하십시오.
편집 : 의견을 바탕으로, 나는 빠른 벤치 마크를 실행하기로 결정 ...
$a = array(); for ($i = 0; $i < 10000; $i++) { $a[] = $i; } $start = microtime(true); foreach ($a as $k => $v) { $a[$k] = $v + 1; } echo "Completed in ", microtime(true) - $start, " Seconds\n"; $start = microtime(true); foreach ($a as $k => &$v) { $v = $v + 1; } echo "Completed in ", microtime(true) - $start, " Seconds\n"; $start = microtime(true); foreach ($a as $k => $v) {} echo "Completed in ", microtime(true) - $start, " Seconds\n"; $start = microtime(true); foreach ($a as $k => &$v) {} echo "Completed in ", microtime(true) - $start, " Seconds\n";
결과 :
Completed in 0.0073502063751221 Seconds Completed in 0.0019769668579102 Seconds Completed in 0.0011849403381348 Seconds Completed in 0.00111985206604 Seconds
따라서 루프에서 배열을 수정하는 경우 참조를 사용하는 것이 몇 배 빠릅니다 ...
그리고 참조에 대한 오버 헤드는 실제로 배열을 복사하는 것보다 작습니다 (5.3.2에 있음) ... 그래서 참조가 상당히 빨라진 것처럼 (적어도 5.3.2에서) 나타납니다.
-
==============================
2.나는 이것이 매우 놀랍다 고 확신하지 못한다. PHP를 코딩하는 대부분의 사람들은 PHP가 베어 메탈에서 실제로하고있는 것에 정통하지 않습니다. 나는 몇 가지 사실을 말할 것인데, 그것은 대부분의 경우 사실 일 것이다.
나는 이것이 매우 놀랍다 고 확신하지 못한다. PHP를 코딩하는 대부분의 사람들은 PHP가 베어 메탈에서 실제로하고있는 것에 정통하지 않습니다. 나는 몇 가지 사실을 말할 것인데, 그것은 대부분의 경우 사실 일 것이다.
이러한 이유 때문에 foreach는 단순한 반복을위한 최선의 선택입니다.
잊지 마세요. 읽기 쉽기 때문에 윈 - 윈 (win-win)입니다.
-
==============================
3.벤치마킹 (특히 phpbench.com)에서 주목해야 할 것은 숫자가 건전하지만 테스트가 아니라는 것입니다. phpbench.com의 테스트 중 많은 부분이 사소한 일이며, 벤치 마크를 왜곡하기 위해 배열 조회를 캐싱하는 PHP의 능력이나 배열을 반복하는 경우 실제로 실제 사례에서는 테스트하지 않습니다. 루프). 나는 내가 본 자신의 벤치 마크를 실제 결과를 상당히 반영하고 있으며, 언어의 네이티브 반복 구문 foreach가 항상 놀랍게 나오는 것을 보여줍니다.
벤치마킹 (특히 phpbench.com)에서 주목해야 할 것은 숫자가 건전하지만 테스트가 아니라는 것입니다. phpbench.com의 테스트 중 많은 부분이 사소한 일이며, 벤치 마크를 왜곡하기 위해 배열 조회를 캐싱하는 PHP의 능력이나 배열을 반복하는 경우 실제로 실제 사례에서는 테스트하지 않습니다. 루프). 나는 내가 본 자신의 벤치 마크를 실제 결과를 상당히 반영하고 있으며, 언어의 네이티브 반복 구문 foreach가 항상 놀랍게 나오는 것을 보여줍니다.
//make a nicely random array $aHash1 = range( 0, 999999 ); $aHash2 = range( 0, 999999 ); shuffle( $aHash1 ); shuffle( $aHash2 ); $aHash = array_combine( $aHash1, $aHash2 ); $start1 = microtime(true); foreach($aHash as $key=>$val) $aHash[$key]++; $end1 = microtime(true); $start2 = microtime(true); while(list($key) = each($aHash)) $aHash[$key]++; $end2 = microtime(true); $start3 = microtime(true); $key = array_keys($aHash); $size = sizeOf($key); for ($i=0; $i<$size; $i++) $aHash[$key[$i]]++; $end3 = microtime(true); $start4 = microtime(true); foreach($aHash as &$val) $val++; $end4 = microtime(true); echo "foreach ".($end1 - $start1)."\n"; //foreach 0.947947025299 echo "while ".($end2 - $start2)."\n"; //while 0.847212076187 echo "for ".($end3 - $start3)."\n"; //for 0.439476966858 echo "foreach ref ".($end4 - $start4)."\n"; //foreach ref 0.0886030197144 //For these tests we MUST do an array lookup, //since that is normally the *point* of iteration //i'm also calling noop on it so that PHP doesn't //optimize out the loopup. function noop( $value ) {} //Create an array of increasing indexes, w/ random values $bHash = range( 0, 999999 ); shuffle( $bHash ); $bstart1 = microtime(true); for($i = 0; $i < 1000000; ++$i) noop( $bHash[$i] ); $bend1 = microtime(true); $bstart2 = microtime(true); $i = 0; while($i < 1000000) { noop( $bHash[$i] ); ++$i; } $bend2 = microtime(true); $bstart3 = microtime(true); foreach( $bHash as $value ) { noop( $value ); } $bend3 = microtime(true); echo "for ".($bend1 - $bstart1)."\n"; //for 0.397135972977 echo "while ".($bend2 - $bstart2)."\n"; //while 0.364789962769 echo "foreach ".($bend3 - $bstart3)."\n"; //foreach 0.346374034882
-
==============================
4.제 생각에는 확실하지 않습니다 : for 루프는 값을 확인하고 증가시키기 위해 두 가지 연산을 필요로합니다. foreach는 메모리에 데이터를로드 한 다음 모든 값을 반복합니다.
제 생각에는 확실하지 않습니다 : for 루프는 값을 확인하고 증가시키기 위해 두 가지 연산을 필요로합니다. foreach는 메모리에 데이터를로드 한 다음 모든 값을 반복합니다.
from https://stackoverflow.com/questions/3430194/performance-of-for-vs-foreach-in-php by cc-by-sa and MIT license
'PHP' 카테고리의 다른 글
PHP cURL을 사용하여 원격 사이트에 로그인하십시오. (0) | 2018.09.14 |
---|---|
페이스 북의 그래프 API로 사진을 앨범에 업로드 (0) | 2018.09.14 |
문자열에서 줄 바꾸기 (0) | 2018.09.14 |
효율적인 JPEG 이미지 크기 조정 (0) | 2018.09.14 |
PHP : array_filter ()를 사용하여 배열 키를 필터링하는 방법은 무엇입니까? (0) | 2018.09.14 |