이 글은 PHP 생성기에 대한 간단한 분석을 소개합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.
제너레이터란 무엇입니까
제너레이터를 사용하면 foreach 블록에 코드를 작성하여 메모리에 배열을 만들지 않고도 데이터 세트를 반복할 수 있습니다. 이로 인해 메모리가 상한에 도달하거나 상당한 처리 시간을 차지하게 됩니다. 대신 일반 사용자 정의 함수처럼 생성기 함수를 작성할 수 있으며, 한 번만 반환하는 일반 함수 대신 생성기는 반복해야 하는 값을 생성하는 데 필요한 만큼 여러 번 생성할 수 있습니다.
간단한 예는 생성기를 사용하여 range() 함수를 다시 구현하는 것입니다. 표준 range() 함수는 해당 범위 내의 모든 값을 포함하는 배열을 메모리에 생성한 다음 배열을 반환하여 여러 개의 큰 배열을 생성해야 합니다. 예를 들어 range(0, 10000)을 호출하면 메모리 사용량이 4MB를 초과하게 됩니다.
예제 코드:
<?php /** * Created by PhpStorm. * User: chenbotome@163.com * Date: 2018/7/30 * Time: 上午11:29 */ $start = xdebug_memory_usage(); $num = 10000; function rangeWithGenerators($start, $limit, $step = 1) { if ($start < $limit) { if ($step <= 0) { throw new LogicException('Step must be +ve'); } for ($i = $start; $i <= $limit; $i += $step) { yield $i; } } else { if ($step >= 0) { throw new LogicException('Step must be -ve'); } for ($i = $start; $i >= $limit; $i += $step) { yield $i; } } } if ($argc === 1) { $iterate = rangeWithGenerators(0, $num, 1); foreach ($iterate as $value){ echo $value . "\n"; } //var_dump(iterator_to_array($iterate)); } if ($argc === 2) { $test = range(0, $num, 1); foreach ($test as $value) { echo $value . "\n"; } } $end = xdebug_memory_usage(); echo sprintf("内存消耗量%s\n", convert($end-$start)); function convert($size){ $unit=array('b','kb','mb','gb','tb','pb'); return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i]; }
Environment
PHP7.1
test.php 반환된 결과: 메모리 소비 416 b
php test.php 범위 결과 반환: 메모리 소비 4MB
코드 실행을 통해 PHP 표준 함수 rang()과 사용자 정의 함수 rangeWithGenerators()의 유사점과 차이점을 비교해 보세요. 동일한 목적을 달성하지만 다른 메모리를 소비한다는 점에서 생성기의 장점은 분명합니다.
rangeWithGenerators()는 생성기를 사용하며 생성기의 핵심은 Yield 키워드를 사용하는 것입니다. 일반적으로 Yield의 사용에는 foreach와 for라는 두 가지 프로세스 제어 문이 포함됩니다. rangeWithGenerators()의 for 루프에 있는 수익률 변수 $i(수익률은 값을 생성하는 것으로 이해될 수 있으며, return이 값을 반환하는 것으로 이해될 수 있는 것처럼).
foreach는 생성기를 반복합니다. 이 예에서 이 메서드는 생성기를 읽는 데 사용됩니다.
PHP 표준 함수 iterator_to_array(), 이 함수는 생성기를 배열로 변환합니다.
위 내용은 PHP 생성기의 간단한 분석 생성기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!