LoginSignup
8
9

More than 5 years have passed since last update.

メモリ節約のためにarray_chunkではなくgeneratorを使う

Last updated at Posted at 2015-12-14

Why

  • 大きいサイズの配列があり、それをある程度の塊として分割して処理をしたい要件があった
  • array_chunk を使うのがコードの見通し的にも望ましかったが、 array_chunk だと塊を内包した配列を生成してしまうので、入力の配列が大きいとメモリの無駄も大きい

対応策

  • generator を使い、分割した塊を yield で返してやる

サンプルコード

<?php

message('start');

$a = range(0, 200000);
message('create array');

$chunkGenerator = function ($array, $size, $preserveKeys = false) {
    $i = 0;
    while (true) {
        $offset = $size * $i++;
        $sliced = array_slice($array, $offset, $size, $preserveKeys);

        if (count($sliced) === 0) {
            break;
        }

        yield $sliced;
    }
};
message('defined generator');

foreach ($chunkGenerator($a, 1000) as $chunk) {
    // nothing to do
}
message('use generator');

foreach (array_chunk($a, 1000) as $chunk) {
    // nothing to do
}
message('use array_chunk');

message('end');

function message($msg)
{
    echo sprintf(
        "%-3d MB %-3d MB %s" . PHP_EOL,
        memory_get_usage() / 1024 / 1024,
        memory_get_peak_usage() / 1024 / 1024,
        $msg
    );
}

出力

$ php chunk.php
0   MB 0   MB start
28  MB 28  MB create array
28  MB 28  MB defined generator
28  MB 28  MB use generator
28  MB 46  MB use array_chunk
28  MB 46  MB end

実行環境

$ php --version
PHP 5.6.7 (cli) (built: Mar 22 2015 19:03:55)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
8
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9