Class declared in MODPATH/codebench/classes/bench/datespan.php on line 7.
$descriptionlink to thisarray
$gradeslink to thisGrade letters with their maximum scores. Used to color the graphs.
$loopslink to this
$subjectslink to thisConstructor.
void
public
function
__construct()
{
parent::__construct();
$this
->subjects =
array
(
time(),
time() -
Date
::MONTH,
time() -
Date
::YEAR,
time() -
Date
::YEAR * 10,
);
}
public
static
function
bench_span_original(
$remote
,
$local
= NULL,
$output
=
'years,months,weeks,days,hours,minutes,seconds'
)
{
// Array with the output formats
$output
= preg_split(
'/[^a-z]+/'
,
strtolower
( (string)
$output
));
// Invalid output
if
(
empty
(
$output
))
return
FALSE;
// Make the output values into keys
extract(
array_flip
(
$output
), EXTR_SKIP);
if
(
$local
=== NULL)
{
// Calculate the span from the current time
$local
= time();
}
// Calculate timespan (seconds)
$timespan
=
abs
(
$remote
-
$local
);
if
(isset(
$years
))
{
$timespan
-=
Date
::YEAR * (
$years
= (int)
floor
(
$timespan
/
Date
::YEAR));
}
if
(isset(
$months
))
{
$timespan
-=
Date
::MONTH * (
$months
= (int)
floor
(
$timespan
/
Date
::MONTH));
}
if
(isset(
$weeks
))
{
$timespan
-=
Date
::WEEK * (
$weeks
= (int)
floor
(
$timespan
/
Date
::WEEK));
}
if
(isset(
$days
))
{
$timespan
-=
Date
::DAY * (
$days
= (int)
floor
(
$timespan
/
Date
::DAY));
}
if
(isset(
$hours
))
{
$timespan
-=
Date
::HOUR * (
$hours
= (int)
floor
(
$timespan
/
Date
::HOUR));
}
if
(isset(
$minutes
))
{
$timespan
-=
Date
::MINUTE * (
$minutes
= (int)
floor
(
$timespan
/
Date
::MINUTE));
}
// Seconds ago, 1
if
(isset(
$seconds
))
{
$seconds
=
$timespan
;
}
// Remove the variables that cannot be accessed
unset(
$timespan
,
$remote
,
$local
);
// Deny access to these variables
$deny
=
array_flip
(
array
(
'deny'
,
'key'
,
'difference'
,
'output'
));
// Return the difference
$difference
=
array
();
foreach
(
$output
as
$key
)
{
if
(isset($
$key
) AND ! isset(
$deny
[
$key
]))
{
// Add requested key to the output
$difference
[
$key
] = $
$key
;
}
}
// Invalid output formats string
if
(
empty
(
$difference
))
return
FALSE;
// If only one output format was asked, don't put it in an array
if
(
count
(
$difference
) === 1)
return
current(
$difference
);
// Return array
return
$difference
;
}
public
static
function
bench_span_use_array(
$remote
,
$local
= NULL,
$output
=
'years,months,weeks,days,hours,minutes,seconds'
)
{
// Array with the output formats
$output
= preg_split(
'/[^a-z]+/'
,
strtolower
( (string)
$output
));
// Invalid output
if
(
empty
(
$output
))
return
FALSE;
// Convert the list of outputs to an associative array
$output
=
array_combine
(
$output
,
array_fill
(0,
count
(
$output
), 0));
// Make the output values into keys
extract(
array_flip
(
$output
), EXTR_SKIP);
if
(
$local
=== NULL)
{
// Calculate the span from the current time
$local
= time();
}
// Calculate timespan (seconds)
$timespan
=
abs
(
$remote
-
$local
);
if
(isset(
$output
[
'years'
]))
{
$timespan
-=
Date
::YEAR * (
$output
[
'years'
] = (int)
floor
(
$timespan
/
Date
::YEAR));
}
if
(isset(
$output
[
'months'
]))
{
$timespan
-=
Date
::MONTH * (
$output
[
'months'
] = (int)
floor
(
$timespan
/
Date
::MONTH));
}
if
(isset(
$output
[
'weeks'
]))
{
$timespan
-=
Date
::WEEK * (
$output
[
'weeks'
] = (int)
floor
(
$timespan
/
Date
::WEEK));
}
if
(isset(
$output
[
'days'
]))
{
$timespan
-=
Date
::DAY * (
$output
[
'days'
] = (int)
floor
(
$timespan
/
Date
::DAY));
}
if
(isset(
$output
[
'hours'
]))
{
$timespan
-=
Date
::HOUR * (
$output
[
'hours'
] = (int)
floor
(
$timespan
/
Date
::HOUR));
}
if
(isset(
$output
[
'minutes'
]))
{
$timespan
-=
Date
::MINUTE * (
$output
[
'minutes'
] = (int)
floor
(
$timespan
/
Date
::MINUTE));
}
// Seconds ago, 1
if
(isset(
$output
[
'seconds'
]))
{
$output
[
'seconds'
] =
$timespan
;
}
if
(
count
(
$output
) === 1)
{
// Only a single output was requested, return it
return
array_pop
(
$output
);
}
// Return array
return
$output
;
}
Runs Codebench on the extending class.
array
- Benchmark output
public
function
run()
{
// Array of all methods to loop over
$methods
=
array_filter
(get_class_methods(
$this
),
array
(
$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 =
array
(
'NULL'
=> NULL);
}
// Initialize benchmark output
$codebench
=
array
(
'class'
=> get_class(
$this
),
'description'
=>
$this
->description,
'loops'
=>
array
(
'base'
=> (int)
$this
->loops,
'total'
=> (int)
$this
->loops *
count
(
$this
->subjects) *
count
(
$methods
),
),
'subjects'
=>
$this
->subjects,
'benchmarks'
=>
array
(),
);
// Benchmark each method
foreach
(
$methods
as
$method
)
{
// Initialize benchmark output for this method
$codebench
[
'benchmarks'
][
$method
] =
array
(
'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
] =
array
(
'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
=
array
(
'time'
=> 999999999,
'memory'
=> 999999999);
$slowest_method
=
$slowest_subject
=
array
(
'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
;
}
Returns the applicable grade letter for a score.
integer|double
$score
required - Scorestring
- Grade letter
protected
function
_grade(
$score
)
{
foreach
(
$this
->grades
as
$max
=>
$grade
)
{
if
(
$max
===
'default'
)
continue
;
if
(
$score
<=
$max
)
return
$grade
;
}
return
$this
->grades[
'default'
];
}
Callback for array_filter(). Filters out all methods not to benchmark.
string
$method
required - Method nameboolean
protected
function
_method_filter(
$method
)
{
// Only benchmark methods with the "bench" prefix
return
(
substr
(
$method
, 0, 5) ===
'bench'
);
}