WordPress.org

Make WordPress Core

Opened 5 years ago

Closed 4 years ago

#10561 closed enhancement (fixed)

Improve do_action(): Make $wp_actions an assoc array.

Reported by: koopersmith Owned by: westi
Milestone: 3.0 Priority: normal
Severity: normal Version: 2.9
Component: Optimization Keywords: has-patch needs-testing early
Focuses: Cc:

Description

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

Attachments (1)

plugin.patch (1.2 KB) - added by koopersmith 5 years ago.
r11782, patch for do_action, did_action, and do_action_ref_array

Download all attachments as: .zip

Change History (11)

koopersmith5 years ago

r11782, patch for do_action, did_action, and do_action_ref_array

comment:1 scribu5 years ago

  • Milestone changed from Unassigned to 2.9
  • Version set to 2.8.3

comment:2 westi5 years ago

  • Owner set to westi
  • Status changed from new to reviewing

Cool.

Would be good to get a patch to add your performance tests to wordpress-tests

http://svn.automattic.com/wordpress-tests/wp-testcase/test_actions.php

It looks like we have some performance tests there but these would be good to add.

comment:3 koopersmith5 years ago

  • Cc koopersmith added

Sounds good, I'll see if I can write a patch for the performance tests sometime soon.

comment:4 ryan4 years ago

  • Milestone changed from 2.9 to Future Release

comment:5 koopersmith4 years ago

  • Version changed from 2.8.3 to 2.9

Just retested this patch on trunk (r12397) with the same results. I'm working on setting up wordpress-tests, and I'll add mine once it's set up.

comment:6 ryan4 years ago

  • Milestone changed from Future Release to 3.0

comment:7 ryan4 years ago

  • Keywords early added

comment:8 Denis-de-Bernardy4 years ago

  • Cc Denis-de-Bernardy added

comment:9 hakre4 years ago

nice find! I like the improvements, want to see this in the sooner the better.

comment:10 ryan4 years ago

  • Resolution set to fixed
  • Status changed from reviewing to closed

(In [12464]) Improve do_action performance. Make an associative array. Props koopersmith. fixes #10561

Note: See TracTickets for help on using tickets.