@ 2014-08-18T08:31:58Z <?php
/*
* This file is part of the SensioLabsProfiler SDK package.
*
* (c) SensioLabs <contact@sensiolabs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class SensioLabsProfilerProbe
{
private static $fileFormat = __CLASS__;
private static $profiler = false;
private static $outputStream;
private static $flags;
private static $options;
private static $defaultOptions = array(
'dump_extensions' => false,
'agent_timeout' => 0.25,
'server_keys' => array(
'HTTP_HOST',
'HTTP_USER_AGENT',
'HTTPS',
'REQUEST_METHOD',
'REQUEST_URI',
'SERVER_ADDR',
'SERVER_SOFTWARE',
),
'ignored_functions' => array(
'array_map',
'array_filter',
'array_reduce',
'array_walk',
'array_walk_recursive',
'call_user_func',
'call_user_func_array',
'call_user_method',
'call_user_method_array',
'forward_static_call',
'forward_static_call_array',
'iterator_apply',
),
);
public static function enable($destination, $flags = null, array $options = array())
{
if (isset(self::$outputStream)) {
self::disable();
}
isset($flags) or $flags = UPROFILER_FLAGS_MEMORY | UPROFILER_FLAGS_CPU;
$requestTime = microtime(true);
if (!$destination) {
return false;
}
if (!empty($options['mock_profile_data']) && is_array($options['mock_profile_data'])) {
self::$profiler = $options['mock_profile_data'];
} elseif (function_exists('uprofiler_enable')) {
self::$profiler = 'uprofiler';
} elseif (function_exists('xhprof_enable')) {
self::$profiler = 'xhprof';
} else {
$flags = 0;
if (!isset(self::$outputStream)) {
user_error('Neither uprofiler nor xhprof extension is enabled');
}
}
$options = array_merge_recursive(self::$defaultOptions, $options);
self::$flags = $flags;
self::$options = $options;
self::profilerEnable();
if (!self::doEnable($destination, $requestTime, $response)) {
self::profilerDisable();
if (null === $response) {
$response = false;
}
}
return null !== $response ? $response : true;
}
public static function disable()
{
if (self::$outputStream) {
self::onEnd('', PHP_OUTPUT_HANDLER_END);
self::$outputStream = false;
return true;
}
}
private static function doEnable($h, $requestTime, &$response)
{
$response = null;
set_error_handler(function ($type, $message, $file, $line) {
throw new ErrorException($message, 0, $type, $file, $line);
});
try {
if (!is_resource($h)) {
if (($f = strpos($h, '://')) && in_array(substr($h, 0, $f), stream_get_transports(), true)) {
if ($h = stream_socket_client($h, $errno, $errstr, 0, STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT)) {
stream_set_timeout($h, 0, self::$options['agent_timeout']*1000000);
$f = array(null, array($h), null);
if (stream_select($f[0], $f[1], $f[2], 0, self::$options['agent_timeout']*1000000)) {
self::fwrite($h, 'SensioLabsProfiler-Request: '.self::$options['agent_request']."\n");
$response = fgets($h, 4096);
if (0 === strpos($response, 'SensioLabsProfiler-Response: ')) {
self::$options['dump_extensions'] = "SensioLabsProfiler-Options: ext\n" === fgets($h, 4096);
} else {
fclose($h);
$h = false;
if (0 !== strpos($response, 'SensioLabsProfiler-Error: ')) {
$response = "SensioLabsProfiler-Error: 102 Invalid agent response ($response)";
}
}
} else {
fclose($h);
$h = false;
$response = "SensioLabsProfiler-Error: 101 agent connection timeout";
}
$f = false;
} else {
$response = "SensioLabsProfiler-Error: 101 $errstr ($errno)";
}
} else {
$f = sprintf('%019.6F', $requestTime).'-';
$f .= substr(str_replace(array('+', '/'), array('', ''), base64_encode(md5(mt_rand(), true))), 0, 6);
$h = fopen($h.'/'.$f.'.log', 'wb');
}
if (!$h) {
restore_error_handler();
return false;
}
}
// This shared lock allows readers to wait for the end of the stream
stream_is_local($h) and flock($h, LOCK_SH);
stream_set_write_buffer($h, 0);
// Loaded extensions list helps understanding runtime behavior
$extensions = array();
if (self::$profiler && self::$options['dump_extensions']) {
foreach (get_loaded_extensions() as $e) {
$extensions[$e] = phpversion($e);
}
}
// Keep only keys from $_COOKIE
$data = array($_COOKIE, array());
array_walk_recursive($data, function (&$v) {$v = strlen($v);});
foreach (self::$options['server_keys'] as $e) {
if (isset($_SERVER[$e])) {
$data[1][$e] = $_SERVER[$e];
}
}
if (isset($_SERVER['HTTP_X_ORIGINAL_URL'])) {
$e = $_SERVER['HTTP_X_ORIGINAL_URL'];
} elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
$e = $_SERVER['HTTP_X_REWRITE_URL'];
} elseif (!empty($_SERVER['IIS_WasUrlRewritten']) && !empty($_SERVER['UNENCODED_URL'])) {
$e = $_SERVER['UNENCODED_URL'];
} elseif (isset($_SERVER['REQUEST_URI'][0])) {
$e = $_SERVER['REQUEST_URI'];
if ('/' !== $e[0]) {
$e = preg_replace('#^https?://[^/]+#', '', $e);
}
} elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
$e = $_SERVER['ORIG_PATH_INFO'];
if (!empty($_SERVER['QUERY_STRING'])) {
$e .= '?'.$_SERVER['QUERY_STRING'];
}
} else {
$e = '';
}
if (!empty($e)) {
$data[1]['REQUEST_URI'] = $e;
}
$data = 'file-format: '.self::$fileFormat."\n"
.'request-mu: '.memory_get_usage(true)."\n"
.'request-pmu: '.memory_get_peak_usage(true)."\n"
.'request-start: '.$requestTime."\n"
.'php-os: '.PHP_OS."\n"
.'php-sapi: '.PHP_SAPI."\n"
.'php-version: '.PHP_VERSION_ID."\n"
// json_encode would loose non-UTF8 data
.'php-extensions: '.base64_encode(serialize($extensions))."\n"
.'_COOKIE: '.base64_encode(serialize($data[0]))."\n"
.'_SERVER: '.base64_encode(serialize($data[1]))."\n";
$e = set_error_handler('var_dump');
restore_error_handler();
restore_error_handler();
$data .=
self::getErrorHandler('error', array(__CLASS__, 'onError'))
.self::getErrorHandler('exception', array(__CLASS__, 'onException'));
set_error_handler($e);
if (self::$profiler && function_exists('sys_getloadavg')) {
$data .= 'sys-load-avg: '.implode(' ', sys_getloadavg())."\n";
}
$data .= "\nmain()//1 0 0 0 0\n\n";
self::fwrite($h, $data);
if (null === self::$outputStream) {
register_shutdown_function(__CLASS__.'::onShutdown');
}
self::$outputStream = $h;
restore_error_handler();
return true;
} catch (ErrorException $e) {
$response = "SensioLabsProfiler-Error: 101 ".rawurlencode($e->getMessage()."\n\n".$e->getTraceAsString());
}
restore_error_handler();
return self::$outputStream = false;
}
private static function getErrorHandler($type, $default = 'var_dump')
{
$s = "set_{$type}_handler";
if ($h = $s($default)) {
$s = "restore_{$type}_handler";
$s();
} elseif ('var_dump' !== $default) {
$h = $default;
}
$type .= '-handler: ';
if ($h instanceof Closure) {
$h = new ReflectionFunction($h);
if (PHP_VERSION_ID >= 50400 && $s = $h->getClosureScopeClass()) {
$h = $s->name.'::{closure}/'.$h->getStartLine().'-'.$h->getEndLine();
} else {
$h = $h->name.'::'.implode('/', array_slice(explode('/', $h->getFileName()), -2)).'/'.$h->getStartLine().'-'.$h->getEndLine();
}
} else {
if (!is_array($h)) {
if (is_object($h)) {
$h = array($h, '__invoke');
} else {
$h = explode('::', $h, 2);
}
}
if (isset($h[1])) {
$h = new ReflectionMethod($h[0], $h[1]);
$h = $h->getDeclaringClass()->name.'::'.$h->name;
} else {
$h = $h[0];
}
}
$type .= "$h\n";
return $type;
}
private static function profilerEnable()
{
if (is_string(self::$profiler)) {
$p = self::$profiler.'_enable';
return $p(self::$flags, self::$options);
}
}
private static function profilerDisable()
{
if (is_string(self::$profiler)) {
$p = self::$profiler.'_disable';
return $p();
} elseif (is_array(self::$profiler)) {
return self::$profiler;
} else {
return array();
}
}
private static function profilerWrite($disable, $chunk = '')
{
set_error_handler('var_dump', 0);
$e = error_reporting(81);
$data = self::profilerDisable();
if (!$disable) {
self::profilerEnable();
}
$h = self::$outputStream;
$chunk .= "\n";
$i = 50; // 50 ~= 4Ko chunks
// Speed optimized paths
if (!$data) {
// No-op
} elseif ((UPROFILER_FLAGS_CPU & self::$flags) && (UPROFILER_FLAGS_MEMORY & self::$flags)) {
foreach ($data as $k => $v) {
$chunk .= "{$k}//{$v['ct']} {$v['wt']} {$v['cpu']} {$v['mu']} {$v['pmu']}\n";
if (0 === --$i) {
self::fwrite($h, $chunk);
$chunk = '';
$i = 50;
}
}
} elseif (UPROFILER_FLAGS_MEMORY & self::$flags) {
foreach ($data as $k => $v) {
$chunk .= "{$k}//{$v['ct']} {$v['wt']} 0 {$v['mu']} {$v['pmu']}\n";
if (0 === --$i) {
self::fwrite($h, $chunk);
$chunk = '';
$i = 50;
}
}
} elseif (UPROFILER_FLAGS_CPU & self::$flags) {
foreach ($data as $k => $v) {
$chunk .= "{$k}//{$v['ct']} {$v['wt']} {$v['cpu']} 0 0\n";
if (0 === --$i) {
self::fwrite($h, $chunk);
$chunk = '';
$i = 50;
}
}
} else {
foreach ($data as $k => $v) {
$chunk .= "{$k}//{$v['ct']} {$v['wt']} 0 0 0\n";
if (0 === --$i) {
self::fwrite($h, $chunk);
$chunk = '';
$i = 50;
}
}
}
if (isset($data['main()'])) {
$chunk .= "main()//-{$data['main()']['ct']} 0 0 0 0\n";
}
$chunk .= "\nrequest-end: ".microtime(true)
."\nrequest-mu: ".memory_get_usage(true)
."\nrequest-pmu: ".memory_get_peak_usage(true)
."\n";
$h = self::fwrite($h, $chunk);
error_reporting($e);
restore_error_handler();
return $h;
}
private static function fwrite($stream, $data)
{
$len = strlen($data);
$written = fwrite($stream, $data);
if (false !== $written) {
while ($written < $len) {
fflush($stream);
$w = fwrite($stream, substr($data, $written));
$written += $w ?: $len + 1;
}
if ($written === $len) {
return true;
}
}
}
/**
* @internal
*/
public static function onError()
{
return false; // Delegate error handling to the internal handler, but adds a line in profiler's data
}
/**
* @internal
*/
public static function onException($e)
{
// Rethrow only, but adds a line in profiler's data
if ('xhprof' === self::$profiler && PHP_VERSION_ID >= 50500) {
self::profilerWrite(true); // Prevents a crash with XHProf
}
throw $e;
}
/**
* @internal
*/
public static function onShutdown()
{
// Get and write data now so that any later fatal error
// do not prevent collecting what we already have.
if (!self::$outputStream) {
return;
}
$e = error_get_last();
register_shutdown_function(__CLASS__.'::onShutdownTail');
$extra = array();
foreach (headers_list() as $data) {
$data = explode(': ', $data, 2);
switch ($data[0]) {
case 'X-Powered-By': continue 2;
case 'Set-Cookie': $data[1] = preg_replace('/=.+?;/', '=[...];', $data[1]);
}
$extra[] = implode(': ', $data);
}
$extra = 'response-headers: '.base64_encode(serialize($extra))."\n"
.(function_exists('http_response_code') ? 'response-code: '.http_response_code()."\n" : '')
.self::getErrorHandler('error')
.self::getErrorHandler('exception');
if (self::$profiler) {
if (isset($e['type'])) {
switch ($e['type']) {
case E_ERROR:
case E_PARSE:
case E_USER_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_RECOVERABLE_ERROR:
$data = explode("\r", $e['message'], 2);
$data = explode("\n", $data[0], 2);
$data[1] = " in {$e['file']}:{$e['line']}";
$data[0] = str_replace($data[1], '', $data[0]);
$extra .= "fatal-error: {$data[0]}{$data[1]}\n";
break;
}
}
}
self::profilerWrite(false, $extra);
}
/**
* @internal
*/
public static function onShutdownTail()
{
// Cleanup remaining output buffers as much as possible
$l = ob_get_level();
while ($l--
&& ($s = ob_get_status())
&& (!empty($s['del'])
|| (isset($s['flags']) && ($s['flags'] & PHP_OUTPUT_HANDLER_REMOVABLE)))
) {
if (!isset($s['flags']) || ($s['flags'] & PHP_OUTPUT_HANDLER_FLUSHABLE)) {
ob_end_flush();
} elseif ($s['flags'] & PHP_OUTPUT_HANDLER_CLEANABLE) {
ob_end_clean();
} else {
break;
}
}
ob_start(__CLASS__.'::onEnd', 4096);
}
/**
* @internal
*/
public static function onEnd($buffer, $mode)
{
if (PHP_OUTPUT_HANDLER_END & $mode) {
if (self::profilerWrite(true)) {
stream_is_local(self::$outputStream) and flock(self::$outputStream, LOCK_UN);
fclose(self::$outputStream);
}
}
return $buffer;
}
}
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).
Version System time (s) User time (s) Memory (MiB) 7.4.1 0.007 0.010 15.27 7.4.0 0.007 0.010 14.96 7.3.13 0.006 0.013 15.00 7.3.12 0.004 0.014 15.08 7.3.11 0.007 0.010 14.75 7.3.10 0.010 0.003 14.80 7.3.9 0.003 0.013 14.86 7.3.8 0.007 0.007 15.04 7.3.7 0.003 0.008 15.00 7.3.6 0.003 0.010 14.80 7.3.5 0.009 0.003 14.93 7.3.4 0.009 0.003 14.94 7.3.3 0.010 0.006 15.00 7.3.2 0.007 0.007 16.64 7.3.1 0.008 0.003 16.59 7.3.0 0.003 0.006 16.57 7.2.26 0.006 0.013 15.26 7.2.25 0.003 0.017 15.09 7.2.24 0.007 0.007 14.66 7.2.23 0.000 0.017 15.34 7.2.22 0.004 0.011 14.94 7.2.21 0.008 0.006 15.09 7.2.20 0.010 0.007 14.91 7.2.19 0.006 0.006 15.02 7.2.18 0.005 0.010 14.98 7.2.17 0.004 0.011 15.20 7.2.16 0.007 0.007 15.00 7.2.15 0.003 0.008 16.58 7.2.14 0.000 0.009 16.52 7.2.13 0.006 0.006 16.52 7.2.12 0.004 0.010 16.30 7.2.11 0.007 0.007 16.54 7.2.10 0.004 0.008 16.59 7.2.9 0.003 0.009 16.64 7.2.8 0.004 0.008 16.86 7.2.7 0.003 0.010 16.59 7.2.6 0.003 0.013 16.66 7.2.5 0.007 0.011 16.63 7.2.4 0.003 0.009 16.55 7.2.3 0.006 0.006 16.91 7.2.2 0.003 0.009 16.82 7.2.1 0.000 0.014 16.71 7.2.0 0.004 0.007 16.38 7.1.33 0.006 0.006 15.64 7.1.32 0.003 0.007 15.58 7.1.31 0.003 0.007 15.72 7.1.30 0.007 0.007 15.63 7.1.29 0.007 0.007 15.36 7.1.28 0.012 0.003 15.75 7.1.27 0.000 0.015 15.58 7.1.26 0.000 0.018 15.65 7.1.25 0.004 0.009 15.75 7.1.24 0.004 0.008 15.44 7.1.23 0.003 0.014 15.45 7.1.22 0.007 0.010 15.75 7.1.21 0.005 0.005 15.74 7.1.20 0.007 0.007 15.47 7.1.19 0.004 0.009 15.53 7.1.18 0.003 0.014 15.60 7.1.17 0.007 0.007 15.53 7.1.16 0.008 0.008 15.63 7.1.15 0.009 0.000 15.29 7.1.14 0.012 0.003 15.36 7.1.13 0.007 0.007 15.62 7.1.12 0.004 0.012 15.65 7.1.11 0.004 0.012 15.79 7.1.10 0.007 0.003 15.26 7.1.9 0.003 0.007 15.72 7.1.8 0.008 0.008 15.24 7.1.7 0.034 0.010 15.64 7.1.6 0.010 0.011 17.52 7.1.5 0.015 0.005 16.14 7.1.4 0.007 0.007 15.38 7.1.3 0.003 0.009 15.54 7.1.2 0.004 0.008 15.74 7.1.1 0.003 0.010 15.42 7.1.0 0.003 0.045 18.88 7.0.33 0.006 0.003 15.24 7.0.32 0.003 0.010 15.12 7.0.31 0.006 0.006 15.18 7.0.30 0.004 0.004 14.96 7.0.29 0.004 0.007 15.19 7.0.28 0.003 0.010 15.43 7.0.27 0.007 0.007 15.44 7.0.26 0.009 0.003 15.47 7.0.25 0.009 0.006 14.91 7.0.24 0.007 0.007 15.25 7.0.23 0.007 0.010 15.30 7.0.22 0.000 0.011 15.15 7.0.21 0.007 0.003 15.31 7.0.20 0.005 0.008 16.14 7.0.19 0.011 0.003 15.42 7.0.18 0.003 0.007 15.12 7.0.17 0.009 0.003 15.05 7.0.16 0.003 0.010 15.35 7.0.15 0.000 0.012 15.01 7.0.14 0.004 0.044 18.66 7.0.13 0.007 0.010 15.39 7.0.12 0.007 0.007 15.46 7.0.11 0.004 0.007 15.47 7.0.10 0.022 0.047 17.60 7.0.9 0.005 0.045 17.54 7.0.8 0.025 0.040 17.77 7.0.7 0.013 0.041 17.70 7.0.6 0.010 0.042 17.64 7.0.5 0.003 0.052 17.98 7.0.4 0.003 0.045 16.58 7.0.3 0.010 0.040 16.66 7.0.2 0.003 0.036 16.71 7.0.1 0.012 0.046 16.71 7.0.0 0.002 0.050 16.61 5.6.40 0.006 0.006 14.15 5.6.39 0.008 0.003 14.59 5.6.38 0.003 0.013 14.20 5.6.37 0.009 0.003 14.29 5.6.36 0.009 0.003 14.50 5.6.35 0.007 0.007 14.67 5.6.34 0.000 0.015 14.14 5.6.33 0.006 0.006 14.12 5.6.32 0.007 0.007 14.29 5.6.31 0.003 0.010 14.10 5.6.30 0.003 0.009 14.23 5.6.29 0.004 0.008 14.54 5.6.28 0.005 0.038 17.75 5.6.27 0.010 0.003 14.05 5.6.26 0.003 0.010 14.17 5.6.25 0.004 0.031 17.49 5.6.24 0.007 0.043 17.37 5.6.23 0.012 0.025 17.40 5.6.22 0.005 0.045 17.32 5.6.21 0.005 0.045 17.51 5.6.20 0.005 0.047 17.68 5.6.19 0.000 0.034 17.70 5.6.18 0.008 0.044 17.63 5.6.17 0.007 0.038 17.65 5.6.16 0.012 0.037 17.70 5.6.15 0.005 0.032 17.68 5.6.14 0.009 0.039 17.71 5.6.13 0.008 0.045 17.85 5.6.12 0.015 0.034 17.73 5.6.11 0.013 0.028 17.69 5.6.10 0.005 0.043 17.86 5.6.9 0.005 0.035 17.82 5.6.8 0.003 0.045 17.30 5.6.7 0.015 0.030 17.40 5.6.6 0.012 0.032 17.29 5.6.5 0.007 0.028 17.45 5.6.4 0.006 0.033 17.48 5.6.3 0.004 0.044 17.24 5.6.2 0.007 0.025 17.31 5.6.1 0.012 0.039 17.20 5.6.0 0.006 0.044 17.33 5.5.38 0.005 0.045 17.34 5.5.37 0.006 0.038 17.37 5.5.36 0.012 0.037 17.13 5.5.35 0.005 0.028 17.32 5.5.34 0.008 0.041 17.53 5.5.33 0.002 0.032 17.44 5.5.32 0.008 0.028 17.68 5.5.31 0.012 0.037 17.54 5.5.30 0.005 0.046 17.61 5.5.29 0.010 0.034 17.60 5.5.28 0.003 0.048 17.54 5.5.27 0.005 0.028 17.49 5.5.26 0.006 0.045 17.49 5.5.25 0.005 0.045 17.33 5.5.24 0.003 0.042 17.05 5.5.23 0.005 0.029 17.21 5.5.22 0.007 0.040 17.04 5.5.21 0.003 0.040 17.29 5.5.20 0.011 0.020 17.21 5.5.19 0.007 0.040 17.13 5.5.18 0.017 0.035 17.18 5.5.17 0.009 0.000 14.01 5.5.16 0.007 0.028 17.11 5.5.15 0.006 0.022 17.16 5.5.14 0.005 0.025 17.14 5.5.13 0.002 0.025 17.04 5.5.12 0.007 0.022 17.25 5.5.11 0.007 0.025 17.25 5.5.10 0.008 0.020 17.19 5.5.9 0.006 0.018 17.25 5.5.8 0.005 0.023 17.19 5.5.7 0.005 0.028 17.25 5.5.6 0.003 0.030 17.22 5.5.5 0.010 0.019 16.93 5.5.4 0.006 0.024 17.07 5.5.3 0.005 0.025 16.94 5.5.2 0.007 0.021 16.95 5.5.1 0.009 0.019 17.06 5.5.0 0.005 0.025 17.02 5.4.45 0.004 0.044 15.27 5.4.44 0.006 0.043 15.34 5.4.43 0.008 0.039 15.19 5.4.42 0.014 0.038 15.19 5.4.41 0.008 0.040 15.27 5.4.40 0.008 0.042 15.14 5.4.39 0.007 0.043 15.03 5.4.38 0.006 0.034 15.00 5.4.37 0.010 0.027 15.09 5.4.36 0.007 0.038 15.06 5.4.35 0.007 0.041 15.10 5.4.34 0.007 0.042 15.03 5.4.33 0.004 0.004 11.05 5.4.32 0.003 0.023 15.15 5.4.31 0.006 0.023 15.00 5.4.30 0.004 0.023 15.00 5.4.29 0.005 0.021 15.07 5.4.28 0.002 0.024 15.17 5.4.27 0.004 0.024 15.03 5.4.26 0.008 0.023 15.07 5.4.25 0.002 0.028 15.02 5.4.24 0.007 0.019 15.15 5.4.23 0.004 0.023 15.09 5.4.22 0.007 0.022 15.06 5.4.21 0.008 0.015 14.97 5.4.20 0.003 0.028 15.07 5.4.19 0.003 0.025 15.04 5.4.18 0.008 0.023 15.08 5.4.17 0.005 0.023 15.06 5.4.16 0.005 0.020 15.00 5.4.15 0.002 0.025 15.07 5.4.14 0.002 0.023 13.77 5.4.13 0.003 0.024 13.74 5.4.12 0.003 0.021 13.74 5.4.11 0.009 0.018 13.77 5.4.10 0.003 0.022 13.73 5.4.9 0.004 0.022 13.74 5.4.8 0.002 0.024 13.73 5.4.7 0.006 0.018 13.80 5.4.6 0.005 0.023 13.73 5.4.5 0.005 0.023 13.81 5.4.4 0.000 0.027 13.77 5.4.3 0.003 0.022 13.75 5.4.2 0.005 0.022 13.69 5.4.1 0.004 0.021 13.78 5.4.0 0.003 0.021 13.48
preferences:dark mode live preview
38.94 ms | 400 KiB | 5 Q