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.
获取阵列的所有键,哪一个具有更好的性能? array_keys还是foreach?我想知道array_keys是否是一个使用foreach循环或for循环的函数来获取密钥..(因为foreach是一种语言结构),所以foreach更好。
But, I'm not sure if array_keys use foreach loop to get the keys
但是,我不确定array_keys是否使用foreach循环来获取密钥
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;
}
5 个解决方案
#1
9
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.
我使用100'000个元素的阵列运行两个脚本(在PHP 5.6上)10'000次,平均执行时间约为0.025秒。
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()
:
但是如果你看看这两个脚本,你会发现使用foreach循环你有点编写更多的代码和一个“无用的”循环,你也可以看到这个带有foreach循环的方法然后产生更多的操作码并使得数量几乎翻倍使用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!
另外正如@EliasVanOotegem的评论中指出的那样,如果代码生成更多的操作码以使其在此处清楚,那并不总是坏事!
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是否是一个使用foreach循环或for循环的函数
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:
array_keys()不直接使用foreach或for循环,但它也遍历数组。您可以在源代码中清楚地看到这一点:
/* {{{ 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)
php源代码
php源码浏览器
VLD vulcan逻辑转储扩展(用于生成操作码)
具有VLD扩展的在线IDE(适用于较小的脚本)
#2
3
None of them, (first one is in fact poor that it has a loop and then array_keys
call too)
没有一个,(第一个实际上很差,它有一个循环,然后array_keys也调用)
Why do this?
为什么这样?
foreach ($value as $key => $value) {
$placeholders[$key] = $value; // Useless loop
}
$keys = array_keys($placeholders);
When you can simply do
当你可以简单地做
$keys = array_keys($value); // if $value is your original array.
This is all you need. See example from PHP Manual
这就是你所需要的。请参阅PHP手册中的示例
$array = array(0 => 100, "color" => "red");
print_r(array_keys($array));
The difference between foreach
and array_keys
in terms of speed will be so negligible that you will have to run a big scale test to even figure out the difference, Just that the array_keys
way looks more neat (subjective).
foreach和array_keys之间在速度方面的差异可以忽略不计,你必须进行大规模测试才能找出差异,只是array_keys方式看起来更整洁(主观)。
#3
2
I run both versions 5x10'000'000 times with the following array:
我使用以下数组运行两个版本5x10'000'000次:
$value = array('a'=>'1','b'=>'2','c'=>'3');
first version
takes 22.61sec
第一个版本需要22.61秒
second version
takes 20.15sec
第二版需要20.15秒
#4
1
A few things you should keep in mind:
你应该记住一些事情:
- Premature optimization is the root of all evil
- If you want to test which of the two approaches is the fastest, write two scripts, run them a couple of thousand times, and compare the average time taken
-
array_keys
does not useforeach
as such, butarray_keys
, internally, iterates over the elements of the array in exactly the same way asforeach
does - PHP arrays are hash tables, their implementation is well documented: here, for example. How a basic array iteration works is explained with C examples, read through it, then look at PHP's source and find the
array_keys
implementation if you want to be absolutely, sure
过早优化是万恶之源
如果你想测试两种方法中哪一种最快,写两个脚本,运行几千次,并比较平均花费的时间
array_keys不使用foreach,但是array_keys在内部以与foreach完全相同的方式遍历数组的元素。
PHP数组是哈希表,它们的实现有很好的记录:例如,这里。如何使用C示例解释基本数组迭代的工作原理,通读它,然后查看PHP的源代码并找到array_keys实现,如果你想绝对,确定
TL;TR
It's entirely possible foreach
is faster (no function call overhead), but it's a lot more verbose to write, and the performance difference between the two won't be the major bottleneck in your project.
Also note that, depending on your PHP version (and cached OP codes), the benchmark scripts might produce different results entirely
完全可能foreach更快(没有函数调用开销),但编写起来更冗长,两者之间的性能差异不会成为项目的主要瓶颈。另请注意,根据您的PHP版本(和缓存的OP代码),基准脚本可能会完全产生不同的结果
#5
0
I'm not sure if i understand correctly what your asking, but i would use foreach to get the values of a array_key like so:
我不确定我是否正确理解你的要求,但我会使用foreach来获取array_key的值,如下所示:
null, 'ZP9098' => null); foreach(array_keys($mykeys) as $key){ echo gettype($key)."\n"; } ?>#1
9
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.
我使用100'000个元素的阵列运行两个脚本(在PHP 5.6上)10'000次,平均执行时间约为0.025秒。
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()
:
但是如果你看看这两个脚本,你会发现使用foreach循环你有点编写更多的代码和一个“无用的”循环,你也可以看到这个带有foreach循环的方法然后产生更多的操作码并使得数量几乎翻倍使用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!
另外正如@EliasVanOotegem的评论中指出的那样,如果代码生成更多的操作码以使其在此处清楚,那并不总是坏事!
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是否是一个使用foreach循环或for循环的函数
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:
array_keys()不直接使用foreach或for循环,但它也遍历数组。您可以在源代码中清楚地看到这一点:
/* {{{ 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)
php源代码
php源码浏览器
VLD vulcan逻辑转储扩展(用于生成操作码)
具有VLD扩展的在线IDE(适用于较小的脚本)
#2
3
None of them, (first one is in fact poor that it has a loop and then array_keys
call too)
没有一个,(第一个实际上很差,它有一个循环,然后array_keys也调用)
Why do this?
为什么这样?
foreach ($value as $key => $value) {
$placeholders[$key] = $value; // Useless loop
}
$keys = array_keys($placeholders);
When you can simply do
当你可以简单地做
$keys = array_keys($value); // if $value is your original array.
This is all you need. See example from PHP Manual
这就是你所需要的。请参阅PHP手册中的示例
$array = array(0 => 100, "color" => "red");
print_r(array_keys($array));
The difference between foreach
and array_keys
in terms of speed will be so negligible that you will have to run a big scale test to even figure out the difference, Just that the array_keys
way looks more neat (subjective).
foreach和array_keys之间在速度方面的差异可以忽略不计,你必须进行大规模测试才能找出差异,只是array_keys方式看起来更整洁(主观)。
#3
2
I run both versions 5x10'000'000 times with the following array:
我使用以下数组运行两个版本5x10'000'000次:
$value = array('a'=>'1','b'=>'2','c'=>'3');
first version
takes 22.61sec
第一个版本需要22.61秒
second version
takes 20.15sec
第二版需要20.15秒
#4
1
A few things you should keep in mind:
你应该记住一些事情:
- Premature optimization is the root of all evil
- If you want to test which of the two approaches is the fastest, write two scripts, run them a couple of thousand times, and compare the average time taken
-
array_keys
does not useforeach
as such, butarray_keys
, internally, iterates over the elements of the array in exactly the same way asforeach
does - PHP arrays are hash tables, their implementation is well documented: here, for example. How a basic array iteration works is explained with C examples, read through it, then look at PHP's source and find the
array_keys
implementation if you want to be absolutely, sure
过早优化是万恶之源
如果你想测试两种方法中哪一种最快,写两个脚本,运行几千次,并比较平均花费的时间
array_keys不使用foreach,但是array_keys在内部以与foreach完全相同的方式遍历数组的元素。
PHP数组是哈希表,它们的实现有很好的记录:例如,这里。如何使用C示例解释基本数组迭代的工作原理,通读它,然后查看PHP的源代码并找到array_keys实现,如果你想绝对,确定
TL;TR
It's entirely possible foreach
is faster (no function call overhead), but it's a lot more verbose to write, and the performance difference between the two won't be the major bottleneck in your project.
Also note that, depending on your PHP version (and cached OP codes), the benchmark scripts might produce different results entirely
完全可能foreach更快(没有函数调用开销),但编写起来更冗长,两者之间的性能差异不会成为项目的主要瓶颈。另请注意,根据您的PHP版本(和缓存的OP代码),基准脚本可能会完全产生不同的结果
#5
0
I'm not sure if i understand correctly what your asking, but i would use foreach to get the values of a array_key like so:
我不确定我是否正确理解你的要求,但我会使用foreach来获取array_key的值,如下所示:
null, 'ZP9098' => null); foreach(array_keys($mykeys) as $key){ echo gettype($key)."\n"; } ?>