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;
}
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.
The array_keys() function returns an array containing the keys.
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.
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.
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With