﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	severity	resolution	keywords	cc
10561	Improve do_action(): Make $wp_actions an assoc array.	koopersmith	westi	"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
}}}
"	enhancement	closed	normal	3.0	Optimization	2.9	normal	fixed	has-patch needs-testing early	koopersmith Denis-de-Bernardy
