Skip to content

Instantly share code, notes, and snippets.

@alganet
Last active December 17, 2015 11:19
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save alganet/5601270 to your computer and use it in GitHub Desktop.
Save alganet/5601270 to your computer and use it in GitHub Desktop.
PHP Self Stats
<?php
// PHP Self Stats
/*
* get_loaded_extensions() returns all the extension names
* currently loaded.
*
* Using array_intersect(), we can get only the extensions
* we want from those which are really available.
*/
$extensions = array_intersect(get_loaded_extensions(), array(
'Core',
'ctype',
'date',
'filter',
'hash',
'iconv',
'json',
'SPL',
'pcre',
'Reflection',
'session',
'standard',
'pdo',
'bcmath',
'mbstring',
'gettext',
'mcrypt',
'sockets',
'tokenizer',
'intl',
'fileinfo',
'Phar',
'apc'
));
/*
* get_extension_funcs() returns all functions from an extension.
*
* array_map() will pass the function get_extension_funcs() on
* all extension names. (get_extension_funcs('Core'),
* get_extension_funcs('ctype'), etc).
*
* After this, we'll have a multi-dimensional array of
* functions by extension. Similar to this:
* array(
* 'Core' => array(...),
* 'ctype' => array(...),
* ...
* )
*
* In order to merge these groups, we need to
* array_merge($core, $ctype, $etc), but no so fast!
*
* call_user_func_array() lets you pass an array as individual
* arguments to a function.
*
* function sum($a, $b) { return $a + $b; }
* call_user_func_array('sum', array(3, 4)); // 7
*
* Since each extension index in the array now is an array
* with more functions, we pass these to array_merge so
* we can get a full list.
*
* Both call_user_func_array() and array_merge works with
* N parameters, not only 2 like our sum() sample.
*/
$all_functions = call_user_func_array(
'array_merge',
array_map('get_extension_funcs', $extensions)
);
/*
* This is another trick to speed up conversions.
*
* array_fill($start, $end, $value) creates an array from
* $start to $end and fill it with $value. We're creating
* here an array of 1s: array(1,1,1,1,1,1,etc).
*
* This array os 1s will have the same size of the
* $all_functions. So we can combine them with array_combine.
*
* Before we had array('strlen', 'strpos', etc...)
* Now we have array('strlen' => 1, 'strpos' => 1);
*
*/
$prefixes = array_combine($all_functions, array_fill(0, count($all_functions), 1));
$prefix_sd = 0;
$best = $prefixes;
$prefix_size = array_reduce(array_map('strlen', array_keys($prefixes)), 'max', 1);
do {
$top = count($prefixes);
$best_prefix_sd = $prefix_sd;
error_log("Trying to find top {$prefix_size}-char prefixes on $top names with more than $best_prefix_sd score...");
$processed = array();
array_walk(
$prefixes,
function ($usages, $prefix_name) use ($prefixes, $prefix_size, &$processed) {
$prefix_length = strlen($prefix_name);
if ($prefix_length > $prefix_size) {
foreach (array_keys($prefixes) as $another_prefix) {
$another_length = strlen($another_prefix);
if ($prefix_name !== $another_prefix
|| $prefix_length < $another_length
|| $another_length > $prefix_size) {
foreach (range(min($prefix_length, $prefix_size), $another_length) as $i) {
if (!substr_compare($prefix_name, $another_prefix, 0, $i)) {
$prefix_length = $i;
} else {
break;
}
}
}
}
$prefix_name = substr($prefix_name, 0, $prefix_length) ?: $prefix_name;
}
if (!isset($processed[$prefix_name])) {
$processed[$prefix_name] = 0;
}
$processed[$prefix_name] = max($processed[$prefix_name] + $usages, 1);
}
);
$prefixes = array_filter($processed);
$prefvals = array_values($prefixes);
$sample_count = count($prefvals);
for ($current_sample = 0; $sample_count > $current_sample; ++$current_sample) {
$sample_square[$current_sample] = pow($prefvals[$current_sample], 2);
}
$prefix_sd = sqrt(
array_sum($sample_square) / $sample_count
- pow((array_sum($prefvals) / $sample_count), 2)
);
if ($prefix_sd >= $best_prefix_sd) {
$best = $prefixes;
$best_prefix_sd = $prefix_sd;
} else {
$prefix_size = array_reduce(array_map('strlen', array_keys($prefixes)), 'max', 1);
}
$prefix_size--;
} while ($prefix_size >= 3);
arsort($best);
print_r(array_slice($best, 0, 10));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment