#18230 closed enhancement (fixed)
Optimize wp_list_pluck
Reported by: | Otto42 | Owned by: | ryan |
---|---|---|---|
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
@
13 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
@
13 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
@
13 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
@
13 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