タイトルは、ループ本体で array_push()
を使用しないでくださいというものですが、実際、これはこの記事の結論の 1 つにすぎません。一緒に勉強しましょう
php 言語で要素を配列に追加する
知っていますでは、これら 2 つの方法の違いは何でしょうか? まずパフォーマンスを比較しましょうArrayPushphp
方法は 2 つあります配列スタックの最後に要素を追加するには
- $a = []; array_push($a,'test');
- $a[] = 'test';
Oneループ追加100 万の要素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; } }ログイン後にコピー
結果は自明です。結果ini_set('memory_limit', '4000M'); $timeOne = microtime(true); $a = ArrayPush::pushEachOne(1000000); echo 'count pushEachOne result | ' . count($a) . PHP_EOL; $timeTwo = microtime(true); $b = ArrayPush::pushEachTwo(1000000); echo 'count pushEachTwo result | ' . count($b) . PHP_EOL; $timeThree = microtime(true); echo PHP_EOL; echo 'pushEachOne | ' . ($timeTwo - $timeOne) . PHP_EOL; echo 'pushEachTwo | ' . ($timeThree - $timeTwo) . PHP_EOL; echo PHP_EOL;ログイン後にコピー
$a[] =array_push() が遅いのはなぜですか?とても遅いのですが、使用できるシナリオはありますか?は
を使用するよりも優れています。 array_push()
ほぼ 3 倍高速分析count pushEachOne result | 1000000 count pushEachTwo result | 1000000 pushEachOne | 1.757071018219 pushEachTwo | 0.67165303230286ログイン後にコピー
公式マニュアルarray_push — 1 つ以上の要素を配列の末尾にプッシュ (プッシュ)
を参照してください。 $a[] =array_push ( array
& $ array、混合
array_push()$value1
[、混合$...
] ) : intは array はそれをスタックとして扱い、渡された変数を
array
の最後にプッシュします。array
の長さは、スタックにプッシュされる変数の数に応じて増加します。<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><?php$array[] = $var;?></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))); } /* }}} */ログイン後にコピー
の実装は、割り当てられた変数タイプに従って一連の 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(&tmp, n);
return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
}
/* }}} */
ZEND_API int add_next_index_null(zval *arg) /* {{{ */
{
zval tmp;
ZVAL_NULL(&tmp);
return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
}
/* }}} */
ZEND_API int add_next_index_bool(zval *arg, int b) /* {{{ */
{
zval tmp;
ZVAL_BOOL(&tmp, b);
return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
}
/* }}} */
ZEND_API int add_next_index_resource(zval *arg, zend_resource *r) /* {{{ */
{
zval tmp;
ZVAL_RES(&tmp, r);
return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
}
/* }}} */
ZEND_API int add_next_index_double(zval *arg, double d) /* {{{ */
{
zval tmp;
ZVAL_DOUBLE(&tmp, d);
return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
}
/* }}} */
ZEND_API int add_next_index_str(zval *arg, zend_string *str) /* {{{ */
{
zval tmp;
ZVAL_STR(&tmp, str);
return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
}
/* }}} */
ZEND_API int add_next_index_string(zval *arg, const char *str) /* {{{ */
{
zval tmp;
ZVAL_STRING(&tmp, str);
return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp) ? SUCCESS : FAILURE;
}
/* }}} */
ZEND_API int add_next_index_stringl(zval *arg, const char *str, size_t length) /* {{{ */
{
zval tmp;
ZVAL_STRINGL(&tmp, str, length);
return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &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[] =
を使用して置き換える必要があります
以上がループ本体内で array_push() を使用しないでください。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。