ホームページ > バックエンド開発 > PHPチュートリアル > ループ本体内で array_push() を使用しないでください。

ループ本体内で array_push() を使用しないでください。

步履不停
リリース: 2023-04-06 22:54:01
オリジナル
3834 人が閲覧しました

ループ本体内で array_push() を使用しないでください。

タイトルは、ループ本体で array_push() を使用しないでくださいというものですが、実際、これはこの記事の結論の 1 つにすぎません。一緒に勉強しましょう
php 言語で要素を配列に追加する

要素を配列に追加する

知っています

php 方法は 2 つあります配列スタックの最後に要素を追加するには

  • $a = []; array_push($a,'test');
  • $a[] = 'test';
では、これら 2 つの方法の違いは何でしょうか?

まずパフォーマンスを比較しましょう

ArrayPush

One

ArrayPush Class

  • pushEachOne ( ) ループ本体で array_push() を使用して要素を $a
  • pushEachTwo() ループ内で ## を使用しますbody #$a[] = $var に要素を追加します $a
/**
 * Class ArrayPush
 */
class ArrayPush
{

    /**
     * @param int $times
     * @return array
     */
    public static function pushEachOne(int $times): array
    {
        $a = [];
        $b = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
        for ($i = 0; $i < $times; $i++) {
            array_push($a, $b[$i % 10]);
        }
        return $a;
    }

    /**
     * @param int $times
     * @return array
     */
    public static function pushEachTwo(int $times): array
    {
        $a = [];
        $b = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
        for ($i = 0; $i < $times; $i++) {
            $a[] = $b[$i % 10];
        }
        return $a;
    }

}
ログイン後にコピー
コードの作成テスト

ループ追加100 万の要素

ini_set(&#39;memory_limit&#39;, &#39;4000M&#39;);
$timeOne = microtime(true);
$a       = ArrayPush::pushEachOne(1000000);
echo &#39;count pushEachOne result | &#39; . count($a) . PHP_EOL;
$timeTwo = microtime(true);
$b       = ArrayPush::pushEachTwo(1000000);
echo &#39;count pushEachTwo result | &#39; . count($b) . PHP_EOL;
$timeThree = microtime(true);
echo PHP_EOL;
echo &#39;pushEachOne | &#39; . ($timeTwo - $timeOne) . PHP_EOL;
echo &#39;pushEachTwo | &#39; . ($timeThree - $timeTwo) . PHP_EOL;
echo PHP_EOL;
ログイン後にコピー

結果

結果は自明です。
$a[] =

を使用するよりも優れています。 array_push() ほぼ 3 倍高速

count pushEachOne result | 1000000
count pushEachTwo result | 1000000

pushEachOne | 1.757071018219
pushEachTwo | 0.67165303230286
ログイン後にコピー

分析

array_push() が遅いのはなぜですか?とても遅いのですが、使用できるシナリオはありますか?

公式マニュアル

array_push — 1 つ以上の要素を配列の末尾にプッシュ (プッシュ)

array_push ( array

& $ array

、混合 $value1 [、混合 $... ] ) : int

array_push()

array はそれをスタックとして扱い、渡された変数を array の最後にプッシュします。 array の長さは、スタックにプッシュされる変数の数に応じて増加します。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">&lt;?php$array[] = $var;?&gt;</pre><div class="contentsignin">ログイン後にコピー</div></div> と同じ効果があり、受信値ごとに上記のアクションを繰り返します。 <p></p> <blockquote>注 <p>: <strong>array_push()</strong> を使用して配列にユニットを追加する場合は、<strong>\$array[] を使用することをお勧めします。 =</strong> 、関数を呼び出す追加の負担がないためです。 <em></em></p>注<p>: <strong>array_push()</strong> は、最初の引数が配列でない場合に警告を発行します。これは、新しい配列を作成する <strong>\$var[]</strong> の動作とは異なります。 <em></em></p> </blockquote>公式ソース コード</blockquote> <h2></h2>次の <blockquote>array_push()<p><code>

/* {{{ proto int array_push(array stack, mixed var [, mixed ...])
   Pushes elements onto the end of the array */
PHP_FUNCTION(array_push)
{
    zval   *args,       /* Function arguments array */
           *stack,      /* Input array */
            new_var;    /* Variable to be pushed */
    int i,              /* Loop counter */
        argc;           /* Number of function arguments */

    //这一段是函数的参数解析
    ZEND_PARSE_PARAMETERS_START(2, -1)
        Z_PARAM_ARRAY_EX(stack, 0, 1)
        Z_PARAM_VARIADIC('+', args, argc)
    ZEND_PARSE_PARAMETERS_END();

    /* For each subsequent argument, make it a reference, increase refcount, and add it to the end of the array */
    for (i = 0; i < argc; i++) {
        //拷贝一个
        ZVAL_COPY(&new_var, &args[i]);

        //插入新数值,自动
        if (zend_hash_next_index_insert(Z_ARRVAL_P(stack), &new_var) == NULL) {
            if (Z_REFCOUNTED(new_var)) Z_DELREF(new_var);
            php_error_docref(NULL, E_WARNING, "Cannot add element to the array as the next element is already occupied");
            RETURN_FALSE;
        }
    }

    /* Clean up and return the number of values in the stack */
    RETVAL_LONG(zend_hash_num_elements(Z_ARRVAL_P(stack)));
}
/* }}} */
ログイン後にコピー
を参照してください。 $a[] =

の実装は、割り当てられた変数タイプに従って一連の Zend_API 関数 add_next_index_* を呼び出すことです。これらは、zval を設定した直後に呼び出されます。 zend_hash_next_index_insert<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">ZEND_API int add_next_index_long(zval *arg, zend_long n) /* {{{ */ {     zval tmp;     ZVAL_LONG(&amp;tmp, n);     return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &amp;tmp) ? SUCCESS : FAILURE; } /* }}} */ ZEND_API int add_next_index_null(zval *arg) /* {{{ */ {     zval tmp;     ZVAL_NULL(&amp;tmp);     return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &amp;tmp) ? SUCCESS : FAILURE; } /* }}} */ ZEND_API int add_next_index_bool(zval *arg, int b) /* {{{ */ {     zval tmp;     ZVAL_BOOL(&amp;tmp, b);     return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &amp;tmp) ? SUCCESS : FAILURE; } /* }}} */ ZEND_API int add_next_index_resource(zval *arg, zend_resource *r) /* {{{ */ {     zval tmp;     ZVAL_RES(&amp;tmp, r);     return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &amp;tmp) ? SUCCESS : FAILURE; } /* }}} */ ZEND_API int add_next_index_double(zval *arg, double d) /* {{{ */ {     zval tmp;     ZVAL_DOUBLE(&amp;tmp, d);     return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &amp;tmp) ? SUCCESS : FAILURE; } /* }}} */ ZEND_API int add_next_index_str(zval *arg, zend_string *str) /* {{{ */ {     zval tmp;     ZVAL_STR(&amp;tmp, str);     return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &amp;tmp) ? SUCCESS : FAILURE; } /* }}} */ ZEND_API int add_next_index_string(zval *arg, const char *str) /* {{{ */ {     zval tmp;     ZVAL_STRING(&amp;tmp, str);     return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &amp;tmp) ? SUCCESS : FAILURE; } /* }}} */ ZEND_API int add_next_index_stringl(zval *arg, const char *str, size_t length) /* {{{ */ {     zval tmp;     ZVAL_STRINGL(&amp;tmp, str, length);     return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &amp;tmp) ? SUCCESS : FAILURE; } /* }}} */ ZEND_API int add_next_index_zval(zval *arg, zval *value) /* {{{ */ {     return zend_hash_next_index_insert(Z_ARRVAL_P(arg), value) ? SUCCESS : FAILURE; } /* }}} */</pre><div class="contentsignin">ログイン後にコピー</div></div>要約

上記の分析の結果、

array_push()

には存在意味がないようです。これは本当にそうなのでしょうか?

一般に、
    array_push()
  • はパフォーマンスが低いため、$array[] = を使用して置き換える必要があります
  • 一度に複数のユニットを追加する場合は、
  • array_push()を使用してください。

  • PHP 関連の技術記事の詳細については、
PHP チュートリアル

コラムをご覧ください。学習のために!

以上がループ本体内で array_push() を使用しないでください。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
php
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート