Php 获取所有密钥时数组\u密钥与foreach
在获取数组的所有密钥时,哪一个具有更好的性能? 数组\u键还是foreach? 我想知道array_keys是一个使用foreach循环还是for循环来获取键的函数。。(因为foreach是一种语言构造),所以foreach更好 但是,我不确定数组_键是否使用foreach循环来获取键 那么,哪一个更好Php 获取所有密钥时数组\u密钥与foreach,php,arrays,Php,Arrays,在获取数组的所有密钥时,哪一个具有更好的性能? 数组\u键还是foreach? 我想知道array_keys是一个使用foreach循环还是for循环来获取键的函数。。(因为foreach是一种语言构造),所以foreach更好 但是,我不确定数组_键是否使用foreach循环来获取键 那么,哪一个更好 foreach ($value as $key => $value) { $pkey = ':' . $key; $placeholders[$pkey] = $value
foreach ($value as $key => $value) {
$pkey = ':' . $key;
$placeholders[$pkey] = $value;
}
$value = array_keys($placeholders);
或
其中没有一个(第一个实际上很差,因为它有一个循环,然后array\u keys
call)
为什么要这样做
foreach ($value as $key => $value) {
$placeholders[$key] = $value; // Useless loop
}
$keys = array_keys($placeholders);
当你可以简单地做
$keys = array_keys($value); // if $value is your original array.
这就是你所需要的。参见
$array = array(0 => 100, "color" => "red");
print_r(array_keys($array));
就速度而言,
foreach
和array\u key
之间的差异可以忽略不计,以至于您必须运行一个大规模的测试来找出差异,只是array\u key
方式看起来更整洁(主观)。您应该记住以下几点:
array\u-keys
不使用foreach
,但是array\u-keys
在内部以与foreach
完全相同的方式迭代数组元素array\u键
实现foreach
速度更快(没有函数调用开销),但编写起来要繁琐得多,而且两者之间的性能差异不会成为项目中的主要瓶颈。还要注意,根据您的PHP版本(和缓存的操作代码),基准脚本可能会产生完全不同的结果我使用以下数组运行两个版本5x10'000'000次:
$value = array('a'=>'1','b'=>'2','c'=>'3');
第一版
需要22.61秒
第二版
需要20.15秒
我不确定是否正确理解您的要求,但我会使用foreach获取数组键的值,如下所示:
空,'ZP9098'=>空);
foreach(数组_键($mykey)作为$key){
echo gettype($key)。“\n”}
?>就性能而言,它们几乎是一样的。你无法真正衡量差异,因此简单地说:过早优化是万恶之源。
使用最可靠、最容易维护、记录和解释的代码段。完成代码编写后,开始分析代码,然后考虑优化主要瓶颈 我用10万个元素的数组运行了这两个脚本(在PHP5.6上)10000次,平均执行时间约为0.025秒 脚本1:
<?php
$arr = range(1, 100000);
$keys = array_keys($arr);
?>
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
脚本2:
<?php
$arr = range(1, 100000);
foreach($arr as $k => $v)
$keys[] = $k;
?>
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
我想知道array_keys是使用foreach循环还是for循环的函数
array\u keys()
不直接使用foreach或for循环,但它也在数组中循环。您可以在以下列表中非常清楚地看到这一点:
旁注:
- (用于生成操作码)
- (对于较小的脚本)
$placeholder
不是空的,并且因为我正在数组上循环,所以我会为那个美丽的内幕故事:)zend\u hash\u internal\u pointer\u reset\u ex
+而({zend\u hash\u move\u forward ex}
只是一个简短的问题:您是如何获得编译器信息的?@Rizier123:要点:-P.PS,一个小问题:如果OP运行的是php>=5.5,生成更多的操作码并不总是一件坏事,相比于调用“数组键”
,这是一个比一些获取和分配更昂贵的操作(但深入到这么多细节可能会让OP感到困惑)@Rizier123:+1对于这个非常完整的答案,如果你不介意的话,我只想补充一句老话“过早优化是万恶之源”作为某种免责声明,在编辑之后,似乎您正在使用此数组来准备语句?您也可以不使用这些:
,这样可以节省一个额外的循环FWIW@Hanky웃Panky是的,你是对的。但是,sql语句中必须有:
。因此,我得到了前面有:
的键。(键是列名)。之后,我将值绑定到$placeholder重新运行它。第一个版本的速度仍然稍快。
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
/* {{{ 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);
}
}
/* }}} */