#18230 closed enhancement (fixed)
Optimize wp_list_pluck
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 3.3 | Priority: | normal |
| Severity: | normal | Version: | |
| Component: | Performance | Keywords: | has-patch |
| Focuses: | Cc: |
Description
wp_list_pluck is a bit slow when dealing with objects, due to the array cast. Since we mostly use objects, this is a problem.
Proof code of a speedup enhancement:
function old_wp_list_pluck( $list, $field ) {
foreach ( $list as $key => $value ) {
$value = (array) $value;
$list[ $key ] = $value[ $field ];
}
return $list;
}
function new_wp_list_pluck( $list, $field ) {
foreach ( $list as $key => $value ) {
if (is_object($value)) $list[$key] = $value->$field;
else $list[$key] = $value[ $field ];
}
return $list;
}
// tested on a site with about 40 tags in the DB
$terms = get_terms('post_tag');
// run both old an new code 10000 times and measure the differences
$start = microtime(true);
for ($i = 1; $i <= 10000; $i++) {
old_wp_list_pluck($terms,'name');
}
$end = microtime(true);
var_dump($end - $start);
$start = microtime(true);
for ($i = 1; $i <= 10000; $i++) {
new_wp_list_pluck($terms,'name');
}
$end = microtime(true);
var_dump($end - $start);
Result:
float(0.85771203041077)
float(0.36069202423096)
New version is slightly more than twice as fast.
Patch forthcoming.
Attachments (1)
Change History (11)
#3
@
14 years ago
Using isset instead of is_object is a little bit faster apparently.
function new1_wp_list_pluck( $list, $field ) {
foreach ( $list as $key => $value ) {
if ( isset( $value->$field ) ) $list[$key] = $value->$field;
else $list[$key] = $value[ $field ];
}
return $list;
}
A simple test with 27 terms.
float(0.71514010429382) // old_wp_list_pluck float(0.33222508430481) // new_wp_list_pluck float(0.26003003120422) // new1_wp_list_pluck
#4
@
14 years ago
Unfortunately, isset() returns false if $value->$field exists but is set to the null value. So it won't fit with all cases. Using is_object is safer.
#5
@
14 years ago
A note, property_exists() (the equivalent for array_key_exists) doesn't verify magic __get() properties, so I would stick to is_object().
Perhaps we could cache is_object() (pull it outside the loop, etc.) and assume wp_list_pluck() will be operating on only objects or only arrays at any given time.
#6
@
14 years ago
If you make that assumption that the $list array is full of similar objects or arrays, you do get a big speedup.
function new2_wp_list_pluck( $list, $field ) {
if ( is_object( $list[0] ) ) {
foreach ( $list as $key => $value )
$list[ $key ] = $value->$field;
} else {
foreach ( $list as $key => $value )
$list[ $key ] = $value[ $field ];
}
return $list;
}
float(1.2270720005035) : OLD
float(0.61718487739563) : NEW
float(0.35837507247925) : NEW2
optimize wp_list_pluck a little bit