[wp-trac] [WordPress Trac] #10561: Improve do_action(): Make $wp_actions an assoc array.
WordPress Trac
wp-trac at lists.automattic.com
Thu Aug 6 20:48:19 UTC 2009
#10561: Improve do_action(): Make $wp_actions an assoc array.
--------------------------+-------------------------------------------------
Reporter: koopersmith | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone: Unassigned
Component: Optimization | Version:
Severity: normal | Keywords: has-patch, needs-testing
--------------------------+-------------------------------------------------
I was benchmarking a few functions in wp-includes/plugin.php and came
across some strange results: for 10000 blank hooks, do_action took 8.75
seconds to run, while apply_filters took only 0.04 seconds. I found the
bottleneck in do_action, and wrote a patch that brought the 8.75 seconds
down to 0.05 seconds.
Currently, $wp_actions is an unordered array of action $tags (strings).
do_action, did_action, and do_action_ref_array all have a time complexity
of O(n) (where n is the size of $wp_action), while their counterparts have
a time complexity of O(1). While this doesn't affect performance for low
values of n, as the size of $wp_action increases, the performance of the
do_action family drastically decreases.
This time complexity can be attributed to two things in do_action:
is_array($wp_actions) and $wp_actions[] = $tag. Both calls traverse the
entirety of $wp_actions—this is what bogs do_action down. In did_action,
we run into the same problem by using array_keys.
is_array can easily be changed to isset, since the $wp_actions global is
only used by do_action, did_action, and do_action_ref_array. If $wp_action
is converted to an associative array with $wp_action[$tag] =
number_of_times_$tag_called, we'll no longer have to traverse the array to
get or set values. The time complexity will drop to the ideal O(1). As a
side effect, the array will also be smaller.
Current Benchmark:
{{{
Benchmark take 1: do_action, 10000 blank actions. Time
elapsed: 8.75771
Benchmark take 1: apply_filters, 10000 blank filters. Time
elapsed: 0.03978
Benchmark take 1: has_action, 10000 blank actions. Time
elapsed: 0.02783
Benchmark take 1: has_filter, 10000 blank filters. Time
elapsed: 0.01878
Benchmark take 1: did_action, run 1000x, 10000 actions. Time
elapsed: 3.27091
Benchmark take 2: do_action, 10000 blank actions. Time
elapsed: 29.29273
Benchmark take 2: apply_filters, 10000 blank filters. Time
elapsed: 0.03888
Benchmark take 2: has_action, 10000 blank actions. Time
elapsed: 0.02708
Benchmark take 2: has_filter, 10000 blank filters. Time
elapsed: 0.01924
Benchmark take 2: did_action, run 1000x, 20000 actions. Time
elapsed: 6.901
}}}
Patch Benchmark:
{{{
Benchmark take 1: do_action, 10000 blank actions. Time
elapsed: 0.0474
Benchmark take 1: apply_filters, 10000 blank filters. Time
elapsed: 0.04281
Benchmark take 1: has_action, 10000 blank actions. Time
elapsed: 0.03405
Benchmark take 1: has_filter, 10000 blank filters. Time
elapsed: 0.02335
Benchmark take 1: did_action, run 1000x, 10000 actions. Time
elapsed: 0.00214
Benchmark take 2: do_action, 10000 blank actions. Time
elapsed: 0.04876
Benchmark take 2: apply_filters, 10000 blank filters. Time
elapsed: 0.03999
Benchmark take 2: has_action, 10000 blank actions. Time
elapsed: 0.0312
Benchmark take 2: has_filter, 10000 blank filters. Time
elapsed: 0.02353
Benchmark take 2: did_action, run 1000x, 20000 actions. Time
elapsed: 0.00213
}}}
--
Ticket URL: <http://core.trac.wordpress.org/ticket/10561>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software
More information about the wp-trac
mailing list