• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

不要在循环体中使用 array_push ()

php 搞代码 3年前 (2022-01-20) 17次浏览 已收录 0个评论

标题是不要在循环体中使用 array_push(),其实这只是本篇文章的结论之一

下面我们一起研究一下 php 语言中数组的追加元素

向数组追加元素

我们知道 php 在数组栈尾追加元素的方式有两种

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

那么这两种方式有什么区别呢?

我们先来比较一下性能

ArrayPush一个 ArrayPush 类pushEachOne() 循环体中使用 array_push() 来为 $a 追加元素pushEachTwo() 循环体中使用 $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('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() 快了接近三倍

count pushEachOne result | 1000000count pushEachTwo result | 1000000pushEachOne | 1.757071018219pushEachTwo | 0.67165303230286

分析

array_push () 为什么慢?这么慢,我们还有使用它的场景吗?

官方手册

array_push — 将一个或多个单元压入数组的末尾(入栈)array_push ( array &$array , mixed $value1 [, mixed $... ] ) : intarray_push() 将 array 当成一个栈,并将传入的变量压入 array 的末尾。array 的长度将根据入栈变量的数目增加。和如下效果相同:<?php$array[] = $var;?>

并对每个传入的值重复以上动作。

● Note: 如果用 array_push() 来给数组增加一个单元,还不如用 \$array[] = ,因为这样没有调用函数的额外负担。

● Note: 如果第一个参数不是数组,array_push() 将发出一条警告。这和 \$var[] 的行为不同,后者会新建一个数组。

官方源码

看一下源码中的 array_push()

/* {{{ proto int array_push(array stack, mixed var [, mixed ...])   Pushes element<div style="color:transparent">!本文来源gaodai.ma#com搞##代!^码网(</div><sup>搞gaodaima代码</sup>s 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)));}/* }}} */

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:不要在循环体中使用 array_push ()

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址