Skip to content

Instantly share code, notes, and snippets.

@jbrinley
Last active December 28, 2015 14:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbrinley/7518483 to your computer and use it in GitHub Desktop.
Save jbrinley/7518483 to your computer and use it in GitHub Desktop.
17817 Performance Test - Benchmarks the patch submitted at http://core.trac.wordpress.org/ticket/17817
<?php
require_once( dirname( __FILE__ ) . '/test_17817_shared.php' );
if ( isset($_SERVER['HTTP_HOST']) ) { echo "<pre>"; }
printf( "Running %d times with %d callbacks\n", TICKET_17817_LOOP_COUNT, TICKET_17817_CALLBACK_COUNT );
$old_path = dirname( __FILE__ ) . '/test_17817_old.php';
$new_path = dirname( __FILE__ ) . '/test_17817_new.php';
$old_results = unserialize( shell_exec( sprintf( 'php "%s"', $old_path ) ) );
$new_results = unserialize( shell_exec( sprintf( 'php "%s"', $new_path ) ) );
printf( "Total Time (Old): %02f\n", $old_results['total'] );
printf( "Average Time (Old): %02f\n", $old_results['average'] );
printf( "Peak Memory after Old: %d\n", $old_results['memory'] );
echo "\n";
printf( "Total Time (New): %02f\n", $new_results['total'] );
printf( "Average Time (New): %02f\n", $new_results['average'] );
printf( "Peak Memory after New: %d\n", $new_results['memory'] );
echo "\n";
printf( "New runs in %02.2f%% of the time of old.\n", ( $new_results['total'] / $old_results['total'] ) * 100 );
printf( "New runs in %02.2f%% of the memory of old.\n", ( $new_results['memory'] / $old_results['memory'] ) * 100 );
die();
<?php
require_once( dirname( __FILE__ ) . '/test_17817_shared.php' );
require_once( ABSPATH . '/wp-includes/class-wp-hook.php' );
function do_action($tag, $arg = '') {
global $wp_filter, $wp_actions, $wp_current_filter;
if ( ! isset($wp_actions[$tag]) )
$wp_actions[$tag] = 1;
else
++$wp_actions[$tag];
// Do 'all' actions first
if ( isset($wp_filter['all']) ) {
$wp_current_filter[] = $tag;
$all_args = func_get_args();
_wp_call_all_hook($all_args);
}
if ( !isset($wp_filter[$tag]) ) {
if ( isset($wp_filter['all']) )
array_pop($wp_current_filter);
return;
}
if ( !isset($wp_filter['all']) )
$wp_current_filter[] = $tag;
$args = array();
if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)
$args[] =& $arg[0];
else
$args[] = $arg;
for ( $a = 2; $a < func_num_args(); $a++ )
$args[] = func_get_arg($a);
$wp_filter[$tag]->do_action( $args );
array_pop($wp_current_filter);
}
function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
global $wp_filter;
if ( !isset($wp_filter[$tag]) ) {
$wp_filter[$tag] = new WP_Hook();
}
$wp_filter[$tag]->add_filter( $function_to_add, $priority, $accepted_args, $tag );
return true;
}
echo serialize( ticket_17817_run_loop() );
exit();
<?php
require_once( dirname( __FILE__ ) . '/test_17817_shared.php' );
function do_action($tag, $arg = '') {
global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter;
if ( ! isset($wp_actions[$tag]) )
$wp_actions[$tag] = 1;
else
++$wp_actions[$tag];
// Do 'all' actions first
if ( isset($wp_filter['all']) ) {
$wp_current_filter[] = $tag;
$all_args = func_get_args();
_wp_call_all_hook($all_args);
}
if ( !isset($wp_filter[$tag]) ) {
if ( isset($wp_filter['all']) )
array_pop($wp_current_filter);
return;
}
if ( !isset($wp_filter['all']) )
$wp_current_filter[] = $tag;
$args = array();
if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)
$args[] =& $arg[0];
else
$args[] = $arg;
for ( $a = 2; $a < func_num_args(); $a++ )
$args[] = func_get_arg($a);
// Sort
if ( !isset( $merged_filters[ $tag ] ) ) {
ksort($wp_filter[$tag]);
$merged_filters[ $tag ] = true;
}
reset( $wp_filter[ $tag ] );
do {
foreach ( (array) current($wp_filter[$tag]) as $the_ )
if ( !is_null($the_['function']) )
call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
} while ( next($wp_filter[$tag]) !== false );
array_pop($wp_current_filter);
}
function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
global $wp_filter, $merged_filters;
$idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);
$wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
unset( $merged_filters[ $tag ] );
return true;
}
echo serialize( ticket_17817_run_loop() );
exit();
<?php
define('ABSPATH', dirname(dirname(__FILE__)).'/src');
define('TEST_ACTION_NAME', '17817');
define('TICKET_17817_LOOP_COUNT', 1000);
define('TICKET_17817_CALLBACK_COUNT', 1000);
function ticket_17817_callback(){}
function ticket_17817_run_once() {
global $wp_filter;
if ( !isset($wp_filter) ) {
$wp_filter = array();
} elseif ( isset($wp_filter[TEST_ACTION_NAME]) && $wp_filter[TEST_ACTION_NAME] instanceof WP_Hook ) {
$wp_filter[TEST_ACTION_NAME]->remove_all_filters(TEST_ACTION_NAME);
} else {
$wp_filter = array();
}
for ( $i = 0 ; $i < TICKET_17817_CALLBACK_COUNT ; $i++ ) {
add_filter( TEST_ACTION_NAME, 'ticket_17817_callback', rand(1,1000), 1000 );
}
$args = array( TEST_ACTION_NAME );
//for ( $i = 0 ; $i < 100 ; $i++ ) { // for testing with additional callback args
// $args[] = $i;
//}
$start = microtime(TRUE);
call_user_func_array( 'do_action', $args );
$end = microtime(TRUE);
return $end - $start;
}
function ticket_17817_run_loop() {
$times = array();
for ( $i = 0 ; $i < TICKET_17817_LOOP_COUNT ; $i++ ) {
$times[] = ticket_17817_run_once();
}
return array(
'memory' => memory_get_peak_usage(),
'total' => array_sum( $times ),
'average' => ( array_sum( $times ) / TICKET_17817_LOOP_COUNT ),
);
}
function _wp_filter_build_unique_id($tag, $function, $priority) {
global $wp_filter;
static $filter_id_count = 0;
if ( is_string($function) )
return $function;
if ( is_object($function) ) {
// Closures are currently implemented as objects
$function = array( $function, '' );
} else {
$function = (array) $function;
}
if (is_object($function[0]) ) {
// Object Class Calling
if ( function_exists('spl_object_hash') ) {
return spl_object_hash($function[0]) . $function[1];
} else {
$obj_idx = get_class($function[0]).$function[1];
if ( !isset($function[0]->wp_filter_id) ) {
if ( false === $priority )
return false;
$obj_idx .= isset($wp_filter[$tag][$priority]) ? count((array)$wp_filter[$tag][$priority]) : $filter_id_count;
$function[0]->wp_filter_id = $filter_id_count;
++$filter_id_count;
} else {
$obj_idx .= $function[0]->wp_filter_id;
}
return $obj_idx;
}
} else if ( is_string($function[0]) ) {
// Static Calling
return $function[0] . '::' . $function[1];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment