Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

array_keys vs foreach in getting all keys

Tags:

arrays

php

In getting all the keys of an array, which one has better performance ? array_keys or foreach ? I wonder if array_keys is a function that uses foreach loop or for loop, to get the keys.. (since foreach is a language construct), so foreach is better.

But, I'm not sure if array_keys use foreach loop to get the keys

So, which one is better

foreach ($value as $key => $value) {
    $pkey = ':' . $key;
    $placeholders[$pkey] = $value;
}
$value = array_keys($placeholders);

Or

$keys = array();
foreach ($value as $key => $value) {
    $pkey = ':' . $key;
    $placeholders[$pkey] = $value;
    $keys[] = $pkey;
}
like image 960
Terry Djony Avatar asked Apr 10 '15 07:04

Terry Djony


People also ask

What is array_keys () used for?

The array_keys() is a built-in function in PHP and is used to return either all the keys of and array or the subset of the keys. Parameters: The function takes three parameters out of which one is mandatory and other two are optional.

How to get all keys from array in PHP?

The array_keys() function returns an array containing the keys.

How to get only keys from associative array PHP?

Answer: Use the PHP array_keys() function You can use the PHP array_keys() function to get all the keys out of an associative array.

How get key of multidimensional array in PHP?

array_keys() returns the keys, numeric and string, from the array . If a search_value is specified, then only the keys for that value are returned. Otherwise, all the keys from the array are returned.


1 Answers

Performance wise they are pretty much the same you can't really measure a difference, so simply put: Premature optimization is the root of all evil.
Use whichever piece of code is most reliable and easiest to maintain, document and explain. When you're done writing your code, then start profiling it, then think about optimizing the major bottlenecks.

I run both scripts(on PHP 5.6) 10'000 times with a array of 100'000 elements and the average execution was about 0.025 sec.

script1:

<?php

    $arr = range(1, 100000);
    $keys = array_keys($arr);

?>

script2:

<?php

    $arr = range(1, 100000);

    foreach($arr as $k => $v)
        $keys[] = $k;

?>

So from performance view there is no real difference between both methods.

But if you look at both scripts you will see that with the foreach loop you kinda write more code and also a "useless" loop, you can also see this that the method with the foreach loop then generates more opcode and makes almost double the amount of operations as the method with the array_keys():

Also as pointed out in the comments from @EliasVanOotegem it's not always a bad thing if a code generates more opcode to makes this clear here!

script1:

number of ops:  8
compiled vars:  !0 = $arr, !1 = $keys
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   3     0  >   SEND_VAL                                                 1
         1      SEND_VAL                                                 100000
         2      DO_FCALL                                      2  $0      'range'
         3      ASSIGN                                                   !0, $0
   5     4      SEND_VAR                                                 !0
         5      DO_FCALL                                      1  $2      'array_keys'
         6      ASSIGN                                                   !1, $2
         7    > RETURN                                                   1

script2:

number of ops:  14
compiled vars:  !0 = $arr, !1 = $k, !2 = $v, !3 = $keys
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   3     0  >   SEND_VAL                                                 1
         1      SEND_VAL                                                 100000
         2      DO_FCALL                                      2  $0      'range'
         3      ASSIGN                                                   !0, $0
   5     4    > FE_RESET                                         $2      !0, ->12
         5  > > FE_FETCH                                         $3      $2, ->12
         6  >   OP_DATA                                          ~5      
         7      ASSIGN                                                   !2, $3
         8      ASSIGN                                                   !1, ~5
   6     9      ASSIGN_DIM                                               !3
        10      OP_DATA                                                  !1, $8
        11    > JMP                                                      ->5
        12  >   SWITCH_FREE                                              $2
        13    > RETURN                                                   1

I wonder if array_keys is a function that uses foreach loop or for loop

array_keys() doesn't use directly a foreach or for loop, but it also loops through the array. You can see this very clearly in the source code:

/* {{{ proto array array_keys(array input [, mixed search_value[, bool strict]])
   Return just the keys from the input array, optionally only for the specified search_value */
PHP_FUNCTION(array_keys)
{
     zval *input,                /* Input array */
         *search_value = NULL,  /* Value to search for */
        **entry,               /* An entry in the input array */
           res,                 /* Result of comparison */
          *new_val;             /* New value */
    int    add_key;             /* Flag to indicate whether a key should be added */
    zend_bool strict = 0;       /* do strict comparison */
    HashPosition pos;
    int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|zb", &input, &search_value, &strict) == FAILURE) {
        return;
    }

    if (strict) {
        is_equal_func = is_identical_function;
    }

    /* Initialize return array */
    if (search_value != NULL) {
        array_init(return_value);
    } else {
        array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(input)));
    }
    add_key = 1;

    /* Go through input array and add keys to the return array */
    zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
    while (zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void **)&entry, &pos) == SUCCESS) {
        if (search_value != NULL) {
            is_equal_func(&res, search_value, *entry TSRMLS_CC);
            add_key = zval_is_true(&res);
        }

        if (add_key) {
            MAKE_STD_ZVAL(new_val);
            zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(input), new_val, &pos);
            zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val, sizeof(zval *), NULL);
        }

        zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos);
    }
}
/* }}} */

Side Notes:

  • php source code
  • php source browser
  • VLD vulcan logic dumper extension (for generation opcode)
  • online IDE with VLD extensions (for smaller scripts)
like image 168
Rizier123 Avatar answered Sep 28 '22 15:09

Rizier123