Heim  >  Artikel  >  Backend-Entwicklung  >  Verwenden Sie array_push() nicht innerhalb eines Schleifenkörpers

Verwenden Sie array_push() nicht innerhalb eines Schleifenkörpers

步履不停
步履不停Original
2019-07-01 17:43:573786Durchsuche

Verwenden Sie array_push() nicht innerhalb eines Schleifenkörpers

Der Titel darf nicht array_push() in einem Schleifenkörper verwendet werden. Tatsächlich ist dies nur eine der Schlussfolgerungen dieses Artikels
Lassen Sie uns gemeinsam lernen php anhängen zu Arrays in der Sprache Element

Elemente an das Array anhängen

Wir wissen, dass php es zwei Möglichkeiten gibt, Elemente an das Ende des Array-Stapels anzuhängen

  • $a = []; array_push($a,'test');
  • $a[] = 'test';

Was ist also der Unterschied zwischen diesen beiden Methoden?

Vergleichen wir zuerst die Leistung

ArrayPush

Eine ArrayPushKlasse

  • pushEachOne(), die im Schleifenkörper verwendet wirdarray_push(), um Elemente $a
  • an pushEachTwo() anzuhängen. Verwenden Sie $a[] = $var im Schleifenkörper, um Elemente an $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;
    }

}

anzuhängen, um Code zu schreiben Tests

Schleife zum Anhängen von 1 Million Elementen

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;

Ergebnis

Das Ergebnis ist selbstverständlich, $a[] = ist fast schneller als array_push() dreimal verwenden

count pushEachOne result | 1000000
count pushEachTwo result | 1000000

pushEachOne | 1.757071018219
pushEachTwo | 0.67165303230286

Analyse

Warum ist array_push() langsam? Es ist so langsam. Gibt es Szenarien, in denen wir es verwenden können?

Offizielles Handbuch

array_push – Eine oder mehrere Zellen an das Ende des Arrays verschieben (push)

array_push ( array &$array , gemischt $value1 [, gemischt $... ] ): int

array_push() behandelt array als Stapel und schiebt die übergebenen Variablen an das Ende von array . Die Länge von array wird basierend auf der Anzahl der auf den Stapel verschobenen Variablen erhöht. Gleicher Effekt wie:

<?php$array[] = $var;?>

und für jeden übergebenen Wert wiederholen.

Hinweis: Wenn Sie array_push() verwenden, um dem Array eine Einheit hinzuzufügen, ist es besser, $array[] = zu verwenden Weil es keine zusätzliche Belastung durch das Aufrufen von Funktionen gibt.

Hinweis: array_push() gibt eine Warnung aus, wenn das erste Argument kein Array ist. Dies unterscheidet sich vom Verhalten von $var[], das ein neues Array erstellt.

Offizieller Quellcode

Sehen Sie sich den Quellcode an, auf dem array_push()

/* {{{ 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[] = basiert Zuweisung Der Variablentyp ruft eine Reihe von Zend_API-Funktionen add_next_index_* auf, die zend_hash_next_index_insert

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;
}
/* }}} */

nach dem Festlegen eines zval-Werts des entsprechenden Typs direkt aufrufen

Nach der obigen Analyse , es scheint array_push() Es hat keinen Sinn für die Existenz. Ist das wirklich der Fall?

  • Im Allgemeinen ist die Leistung von array_push() zu schlecht, daher sollten wir $array[] = verwenden, um es zu ersetzen.
  • Wenn Sie mehrere Einheiten gleichzeitig anhängen, verwenden Sie array_push()

Weitere PHP-bezogene technische Artikel finden Sie in der Spalte PHP-Tutorial, um mehr darüber zu erfahren!

Das obige ist der detaillierte Inhalt vonVerwenden Sie array_push() nicht innerhalb eines Schleifenkörpers. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn