PHP에서 Array_Walk_Recursive 는 다차원 배열에서 각 요소에서 어떤 종류의 작업을 수행하는 일반적으로 사용되는 기능입니다. 이 기능은 소규모 배열을 처리 할 때 잘 수행되지만 배열이 매우 커지면 성과가 저하 될 수 있습니다. 이 기사는 대형 다차원 배열을 효율적으로 처리하기 위해 Array_Walk_Recursive를 최적화하는 방법을 살펴 봅니다.
Array_Walk_Recursive 의 기본 기능은 다차원 배열을 통해 재귀 적으로 반복하고 각 배열 요소에 콜백 함수를 적용하는 것입니다. 이 기능의 서명은 다음과 같습니다.
<span><span><span class="hljs-keyword">bool</span></span><span> </span><span><span class="hljs-title function_ invoke__">array_walk_recursive</span></span><span> ( </span><span><span class="hljs-keyword">array</span></span><span> &</span><span><span class="hljs-variable">$array</span></span><span> , </span><span><span class="hljs-keyword">callable</span></span><span> </span><span><span class="hljs-variable">$callback</span></span><span> )
</span></span>
$ 배열 : 함수로 전달 된 배열 (참조로 전달).
$ 콜백 : 두 개의 매개 변수를 수용하는 콜백 함수, 첫 번째는 배열의 값이고 두 번째는 배열의 키입니다.
예를 들어, 다음 코드는 2 차원 배열에서 재귀 적으로 작동합니다.
<span><span><span class="hljs-variable">$array</span></span><span> = [
</span><span><span class="hljs-string">'a'</span></span><span> => </span><span><span class="hljs-number">1</span></span><span>,
</span><span><span class="hljs-string">'b'</span></span><span> => [
</span><span><span class="hljs-string">'c'</span></span><span> => </span><span><span class="hljs-number">2</span></span><span>,
</span><span><span class="hljs-string">'d'</span></span><span> => </span><span><span class="hljs-number">3</span></span><span>
]
];
</span><span><span class="hljs-title function_ invoke__">array_walk_recursive</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>, function(&</span><span><span class="hljs-variable">$item</span></span><span>, </span><span><span class="hljs-variable">$key</span></span><span>) {
</span><span><span class="hljs-variable">$item</span></span><span> *= </span><span><span class="hljs-number">2</span></span><span>; </span><span><span class="hljs-comment">// 배열의 각 요소에 곱하십시오 2</span></span><span>
});
</span><span><span class="hljs-title function_ invoke__">print_r</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>);
</span></span>
출력 결과는 다음과 같습니다.
<span><span><span class="hljs-title function_ invoke__">Array</span></span><span>
(
[a] => </span><span><span class="hljs-number">2</span></span><span>
[b] => </span><span><span class="hljs-title function_ invoke__">Array</span></span><span>
(
[c] => </span><span><span class="hljs-number">4</span></span><span>
[d] => </span><span><span class="hljs-number">6</span></span><span>
)
)
</span></span>
Array_Walk_Recursive 는 매우 간결하고 편리한 기능이지만, 특히 많은 양의 데이터를 다룰 때 성능 병목 현상이 있습니다.
재귀 통화 오버 헤드 : Array_walk_Recursive는 다차원 배열을 가로 지르는 재귀에 따라 다릅니다. 각 재귀 호출은 함수 스택의 깊이를 증가시킵니다. 배열 중첩 레이어가 깊이 있으면 스택 오버플로 또는 성능 저하가 발생할 수 있습니다.
반복 계산 : 경우에 따라 Array_Walk_Recursive는 배열의 각 레이어에서 작동합니다. 작업이 복잡하거나 배열이 크면 성능에 큰 영향을 미칩니다.
Array_Walk_Recursive 의 성능을 최적화하기 위해 다음 전략을 시도 할 수 있습니다.
먼저 재귀 처리가 필요한 배열 레이어에서만 작동해야합니다. 비 다소 차원 배열의 경우 array_walk 또는 foreach를 직접 사용하는 것이 더 효율적입니다. 예를 들어:
<span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">optimized_walk</span></span><span>(</span><span><span class="hljs-params">&<span class="hljs-variable">$array</span></span></span><span>) {
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$array</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$key</span></span><span> => &</span><span><span class="hljs-variable">$value</span></span><span>) {
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">is_array</span></span><span>(</span><span><span class="hljs-variable">$value</span></span><span>)) {
</span><span><span class="hljs-title function_ invoke__">optimized_walk</span></span><span>(</span><span><span class="hljs-variable">$value</span></span><span>); </span><span><span class="hljs-comment">// 재귀 작업</span></span><span>
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-variable">$value</span></span><span> *= </span><span><span class="hljs-number">2</span></span><span>; </span><span><span class="hljs-comment">// 개별 요소 처리</span></span><span>
}
}
}
</span><span><span class="hljs-variable">$array</span></span><span> = [
</span><span><span class="hljs-string">'a'</span></span><span> => </span><span><span class="hljs-number">1</span></span><span>,
</span><span><span class="hljs-string">'b'</span></span><span> => [
</span><span><span class="hljs-string">'c'</span></span><span> => </span><span><span class="hljs-number">2</span></span><span>,
</span><span><span class="hljs-string">'d'</span></span><span> => </span><span><span class="hljs-number">3</span></span><span>
]
];
</span><span><span class="hljs-title function_ invoke__">optimized_walk</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">print_r</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>);
</span></span>
이런 식으로, 우리는 array_walk_recursive 의 재귀적인 오버 헤드를 피하고 재귀 깊이를보다 정확하게 제어 할 수 있습니다.
Array_Walk_Recursive 에서 콜백 함수의 첫 번째 매개 변수는 배열 요소의 값입니다. 배열 값을 수정하려면 참조 ( & )별로 매개 변수를 전달해야합니다. 최적화 할 때 특별한주의가 필요합니다.
참조를 사용할 때 메모리 복사 오버 헤드, 특히 큰 배열을 처리 할 때는 줄일 수 있습니다. 예를 들어:
<span><span><span class="hljs-title function_ invoke__">array_walk_recursive</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>, function (&</span><span><span class="hljs-variable">$value</span></span><span>, </span><span><span class="hljs-variable">$key</span></span><span>) {
</span><span><span class="hljs-variable">$value</span></span><span> *= </span><span><span class="hljs-number">2</span></span><span>;
});
</span></span>
이러한 방식으로 & $ value Pass는 많은 양의 데이터 복제를 피하고 메모리 사용량을 줄입니다.
각 재귀 호출은 기능 스택의 깊이를 증가시킵니다. 깊이가 너무 커지면 성능 문제가 발생하고 오버플로 스택이 발생합니다. 따라서 재귀 층의 수를 줄이면 성능 향상에 큰 도움이됩니다. 큐 ( 대기열 ) 또는 스택 데이터 구조를 사용하여 재귀를 시뮬레이션하여 여러 기능 호출 및 스택 깊이 성장을 피할 수있는 재귀를 시뮬레이션하는 것을 고려하십시오.
예:
<span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">iterative_walk</span></span><span>(</span><span><span class="hljs-params">&<span class="hljs-variable">$array</span></span></span><span>) {
</span><span><span class="hljs-variable">$stack</span></span><span> = [&</span><span><span class="hljs-variable">$array</span></span><span>]; </span><span><span class="hljs-comment">// 스택을 사용하여 재귀를 시뮬레이션하십시오</span></span><span>
</span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-variable">$stack</span></span><span>) {
</span><span><span class="hljs-variable">$current</span></span><span> = </span><span><span class="hljs-title function_ invoke__">array_pop</span></span><span>(</span><span><span class="hljs-variable">$stack</span></span><span>);
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$current</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$key</span></span><span> => &</span><span><span class="hljs-variable">$value</span></span><span>) {
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">is_array</span></span><span>(</span><span><span class="hljs-variable">$value</span></span><span>)) {
</span><span><span class="hljs-variable">$stack</span></span><span>[] = &</span><span><span class="hljs-variable">$value</span></span><span>; </span><span><span class="hljs-comment">// 배열이라면,스택을 계속 누릅니다</span></span><span>
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-variable">$value</span></span><span> *= </span><span><span class="hljs-number">2</span></span><span>; </span><span><span class="hljs-comment">// 처리 요소</span></span><span>
}
}
}
}
</span><span><span class="hljs-variable">$array</span></span><span> = [
</span><span><span class="hljs-string">'a'</span></span><span> => </span><span><span class="hljs-number">1</span></span><span>,
</span><span><span class="hljs-string">'b'</span></span><span> => [
</span><span><span class="hljs-string">'c'</span></span><span> => </span><span><span class="hljs-number">2</span></span><span>,
</span><span><span class="hljs-string">'d'</span></span><span> => </span><span><span class="hljs-number">3</span></span><span>
]
];
</span><span><span class="hljs-title function_ invoke__">iterative_walk</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">print_r</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>);
</span></span>
이 예에서는 스택 구조를 사용하여 재귀를 시뮬레이션하여 재귀 호출의 오버 헤드를 피합니다.
타일 다차원 배열의 경우 배열의 구조를 알고 있다면 재귀 작업 대신 array_map 또는 array_merge를 사용할 수 있습니다. 이러한 기능은 일반적으로 Array_Walk_Recursive 보다 빠릅니다. 내부적으로 최적화되기 때문입니다.
예를 들어, array_map을 사용하여 배치 프로세스 어레이를 사용하십시오.
<span><span><span class="hljs-variable">$array</span></span><span> = [</span><span><span class="hljs-number">1</span></span><span>, </span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>, </span><span><span class="hljs-number">4</span></span><span>];
</span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-title function_ invoke__">array_map</span></span><span>(function(</span><span><span class="hljs-variable">$item</span></span><span>) {
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-variable">$item</span></span><span> * </span><span><span class="hljs-number">2</span></span><span>;
}, </span><span><span class="hljs-variable">$array</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">print_r</span></span><span>(</span><span><span class="hljs-variable">$result</span></span><span>);
</span></span>
이 방법은 1 차원 배열에 적합하지만, 다차원 배열을 최적화 할 때 먼저 배열을 1 차원 배열로 변환 한 다음 처리를 크게 향상시킬 수 있습니다.
Array_Walk_Recursive 는 매우 강력한 기능이지만 큰 배열을 처리하는 것이 항상 최선은 아닙니다. 불필요한 재귀를 피하고, 참조를 사용하고, 스택 깊이를 줄이고, 다른 배열 조작 함수를 사용하여 코드의 실행 효율을 효과적으로 향상시킬 수 있습니다.
다차원 배열의 트래버스 성능을 최적화 할 때, 재귀 호출의 오버 헤드를 줄이고 배열 요소를 여러 번 복사하지 않도록하는 것입니다. 큰 배열이 발생할 때 재귀를 반복 또는 기타보다 효율적인 솔루션으로 대체하는 것을 고려하십시오.