Class Bench_GruberURL

Bench_GruberURL

extends Codebench
extends Kohana_Codebench

package
Kohana/Codebench
category
Tests
author
Geert De Deckere <geert@idoe.be>


Properties

public $description

Default value:
string(82) "Optimization for http://daringfireball.net/2009/11/liberal_regex_for_matching_urls"

public array $grades

Grade letters with their maximum scores. Used to color the graphs.

Default value:
array(6) (
    125 => string(1) "A"
    150 => string(1) "B"
    200 => string(1) "C"
    300 => string(1) "D"
    500 => string(1) "E"
    "default" => string(1) "F"
)

public $loops

Default value:
integer 10000

public $subjects

Default value:
array(21) (
    0 => string(24) "http://foo.com/blah_blah"
    1 => string(25) "http://foo.com/blah_blah/"
    2 => string(41) "(Something like http://foo.com/blah_blah)"
    3 => string(36) "http://foo.com/blah_blah_(wikipedia)"
    4 => string(53) "(Something like http://foo.com/blah_blah_(wikipedia))"
    5 => string(25) "http://foo.com/blah_blah."
    6 => string(26) "http://foo.com/blah_blah/."
    7 => string(26) "<http://foo.com/blah_blah>"
    8 => string(27) "<http://foo.com/blah_blah/>"
    9 => string(25) "http://foo.com/blah_blah,"
    10 => string(38) "http://www.example.com/wpstyle/?p=364."
    11 => string(19) "http://✪df.ws/e7l"
    12 => string(11) "rdar://1234"
    13 => string(10) "rdar:/1234"
    14 => string(53) "x-yojimbo-item://6303E4C1-xxxx-45A6-AB9D-3A908F59AE0E"
    15 => string(70) "message://%3c330e7f8409726r6a4ba78dkf1fd71420c1bf6ff@mail.gmail.com%3e"
    16 => string(17) "http://➡.ws/䨹"
    17 => string(14) "www.➡.ws/䨹"
    18 => string(29) "<tag>http://example.com</tag>"
    19 => string(28) "Just a www.example.com link."
    20 => string(119) "httpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp"
)

Methods

public bench_daringfireball() (defined in Bench_GruberURL)

Source Code

public function bench_daringfireball($subject)
{
	// Original regex by John Gruber
	preg_match('~\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))~', $subject, $matches);
	return (empty($matches)) ? FALSE : $matches[0];
}

public bench_daringfireball_v2() (defined in Bench_GruberURL)

Source Code

public function bench_daringfireball_v2($subject)
{
	// Removed outer capturing parentheses, made another pair non-capturing
	preg_match('~\b(?:[\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|(?:[^[:punct:]\s]|/))~', $subject, $matches);
	return (empty($matches)) ? FALSE : $matches[0];
}

public bench_daringfireball_v3() (defined in Bench_GruberURL)

Source Code

public function bench_daringfireball_v3($subject)
{
	// Made quantifiers possessive where possible
	preg_match('~\b(?:[\w-]++://?+|www[.])[^\s()<>]+(?:\([\w\d]++\)|(?:[^[:punct:]\s]|/))~', $subject, $matches);
	return (empty($matches)) ? FALSE : $matches[0];
}

public __construct() (defined in Kohana_Codebench)

Constructor.

Return Values

  • void

Source Code

public function __construct()
{
	// Set the maximum execution time
	set_time_limit(Kohana::$config->load('codebench')->max_execution_time);
}

public run() (defined in Kohana_Codebench)

Runs Codebench on the extending class.

Return Values

  • array - Benchmark output

Source Code

public function run()
{
	// Array of all methods to loop over
	$methods = array_filter(get_class_methods($this), [$this, '_method_filter']);

	// Make sure the benchmark runs at least once,
	// also if no subject data has been provided.
	if (empty($this->subjects))
	{
		$this->subjects = ['NULL' => NULL];
	}

	// Initialize benchmark output
	$codebench = [
		'class'       => get_class($this),
		'description' => $this->description,
		'loops'       => [
			'base'    => (int) $this->loops,
			'total'   => (int) $this->loops * count($this->subjects) * count($methods),
		],
		'subjects'    => $this->subjects,
		'benchmarks'  => [],
	];

	// Benchmark each method
	foreach ($methods as $method)
	{
		// Initialize benchmark output for this method
		$codebench['benchmarks'][$method] = ['time' => 0, 'memory' => 0];

		// Using Reflection because simply calling $this->$method($subject) in the loop below
		// results in buggy benchmark times correlating to the length of the method name.
		$reflection = new ReflectionMethod(get_class($this), $method);

		// Benchmark each subject on each method
		foreach ($this->subjects as $subject_key => $subject)
		{
			// Prerun each method/subject combo before the actual benchmark loop.
			// This way relatively expensive initial processes won't be benchmarked, e.g. autoloading.
			// At the same time we capture the return here so we don't have to do that in the loop anymore.
			$return = $reflection->invoke($this, $subject);

			// Start the timer for one subject
			$token = Profiler::start('codebench', $method.$subject_key);

			// The heavy work
			for ($i = 0; $i < $this->loops; ++$i)
			{
				$reflection->invoke($this, $subject);
			}

			// Stop and read the timer
			$benchmark = Profiler::total($token);

			// Benchmark output specific to the current method and subject
			$codebench['benchmarks'][$method]['subjects'][$subject_key] = [
				'return' => $return,
				'time'   => $benchmark[0],
				'memory' => $benchmark[1],
			];

			// Update method totals
			$codebench['benchmarks'][$method]['time']   += $benchmark[0];
			$codebench['benchmarks'][$method]['memory'] += $benchmark[1];
		}
	}

	// Initialize the fastest and slowest benchmarks for both methods and subjects, time and memory,
	// these values will be overwritten using min() and max() later on.
	// The 999999999 values look like a hack, I know, but they work,
	// unless your method runs for more than 31 years or consumes over 1GB of memory.
	$fastest_method = $fastest_subject = ['time' => 999999999, 'memory' => 999999999];
	$slowest_method = $slowest_subject = ['time' => 0, 'memory' => 0];

	// Find the fastest and slowest benchmarks, needed for the percentage calculations
	foreach ($methods as $method)
	{
		// Update the fastest and slowest method benchmarks
		$fastest_method['time']   = min($fastest_method['time'],   $codebench['benchmarks'][$method]['time']);
		$fastest_method['memory'] = min($fastest_method['memory'], $codebench['benchmarks'][$method]['memory']);
		$slowest_method['time']   = max($slowest_method['time'],   $codebench['benchmarks'][$method]['time']);
		$slowest_method['memory'] = max($slowest_method['memory'], $codebench['benchmarks'][$method]['memory']);

		foreach ($this->subjects as $subject_key => $subject)
		{
			// Update the fastest and slowest subject benchmarks
			$fastest_subject['time']   = min($fastest_subject['time'],   $codebench['benchmarks'][$method]['subjects'][$subject_key]['time']);
			$fastest_subject['memory'] = min($fastest_subject['memory'], $codebench['benchmarks'][$method]['subjects'][$subject_key]['memory']);
			$slowest_subject['time']   = max($slowest_subject['time'],   $codebench['benchmarks'][$method]['subjects'][$subject_key]['time']);
			$slowest_subject['memory'] = max($slowest_subject['memory'], $codebench['benchmarks'][$method]['subjects'][$subject_key]['memory']);
		}
	}

	// Percentage calculations for methods
	foreach ($codebench['benchmarks'] as & $method)
	{
		// Calculate percentage difference relative to fastest and slowest methods
		$method['percent']['fastest']['time']   = (empty($fastest_method['time']))   ? 0 : ($method['time']   / $fastest_method['time']   * 100);
		$method['percent']['fastest']['memory'] = (empty($fastest_method['memory'])) ? 0 : ($method['memory'] / $fastest_method['memory'] * 100);
		$method['percent']['slowest']['time']   = (empty($slowest_method['time']))   ? 0 : ($method['time']   / $slowest_method['time']   * 100);
		$method['percent']['slowest']['memory'] = (empty($slowest_method['memory'])) ? 0 : ($method['memory'] / $slowest_method['memory'] * 100);

		// Assign a grade for time and memory to each method
		$method['grade']['time']   = $this->_grade($method['percent']['fastest']['time']);
		$method['grade']['memory'] = $this->_grade($method['percent']['fastest']['memory']);

		// Percentage calculations for subjects
		foreach ($method['subjects'] as & $subject)
		{
			// Calculate percentage difference relative to fastest and slowest subjects for this method
			$subject['percent']['fastest']['time']   = (empty($fastest_subject['time']))   ? 0 : ($subject['time']   / $fastest_subject['time']   * 100);
			$subject['percent']['fastest']['memory'] = (empty($fastest_subject['memory'])) ? 0 : ($subject['memory'] / $fastest_subject['memory'] * 100);
			$subject['percent']['slowest']['time']   = (empty($slowest_subject['time']))   ? 0 : ($subject['time']   / $slowest_subject['time']   * 100);
			$subject['percent']['slowest']['memory'] = (empty($slowest_subject['memory'])) ? 0 : ($subject['memory'] / $slowest_subject['memory'] * 100);

			// Assign a grade letter for time and memory to each subject
			$subject['grade']['time']   = $this->_grade($subject['percent']['fastest']['time']);
			$subject['grade']['memory'] = $this->_grade($subject['percent']['fastest']['memory']);
		}
	}

	return $codebench;
}

protected _grade(integer|double $score ) (defined in Kohana_Codebench)

Returns the applicable grade letter for a score.

Parameters

  • integer|double $score required - Score

Return Values

  • string - Grade letter

Source Code

protected function _grade($score)
{
	foreach ($this->grades as $max => $grade)
	{
		if ($max === 'default')
			continue;

		if ($score <= $max)
			return $grade;
	}

	return $this->grades['default'];
}

protected _method_filter(string $method ) (defined in Kohana_Codebench)

Callback for array_filter(). Filters out all methods not to benchmark.

Parameters

  • string $method required - Method name

Return Values

  • boolean

Source Code

protected function _method_filter($method)
{
	// Only benchmark methods with the "bench" prefix
	return (substr($method, 0, 5) === 'bench');
}

Do you want to contribute to Koseven?

We need YOUR help!

This project is open source. What does this mean? YOU can help:
  • Found a bug? Report it on Github
  • Need a feature? Add it Here
  • Want to help? Join the Forum
Go to Github