<?php
/*===================*/
/* Тестовая функция. */
/*===================*/
function test ($a)
{
global $testval1, $testval2;
$l = $testval1 * $a;
for ($i = 0; $i < $l; ++$i)
$testval2 .= 'X';
}
/*==================================*/
/* Хронометраж выполнения операций. */
/* Автор: Игорь Орещенков, 2015. */
/*==================================*/
$testval1 = 32;
$testval2 = '';
$n = 10; // количество опытов
$m = 1000; // количество итераций в одном опыте
$di = 0.02; // инструментальная погрешность измерений
$tan = 2.9; // коэффициент доверия (98%;10)
for ($u = 1000; $u < 10001; $u += 1000):
do {
$caption = "Testing string building $u x $testval1 chars length (concatenating).";
echo $caption . "\n";
/*-----------------------------*/
/* Основной цикл эксперимента. */
/*-----------------------------*/
for ($i = 0; $i < $n + 2; ++$i):
$tm1 = microtime_float (); // отметка времени старта
for ($j = 0; $j < $m; ++$j):
$testval2 = '';
test ($u);
endfor;
$tm2 = microtime_float (); // отметка времени финиша
/* Результат хронометража. */
$dt = round ($tm2 - $tm1, 3); $t[] = $dt;
echo "Experiment N $i\n";
echo "Start: $tm1\n";
echo "Finish: $tm2\n";
echo "Elapsed: $dt\n";
endfor;
/*-------------------------------------------------*/
/* Статистическая обработка результатов измерений. */
/*-------------------------------------------------*/
for ($i = 0; $i < $n - 1; ++$i)
$t[$i] = $t[$i + 1];
$tavg = avg ($t); // выборочное среднее
$tsd = stddev ($t, $tavg); // выборочное среднее квадратическое отклонение
/*------------------------------------------------------------------------------*/
/* Оценка минимального и максимального значения с точки зрения критерия Шовене. */
/*------------------------------------------------------------------------------*/
$t1 = $t[0];
$shovz1 = abs ($t1 - $tavg) / $tsd; $t2 = $t[$n - 1];
$shovz2 = abs ($t2 - $tavg) / $tsd; $shovm1 = shovene ($shovz1); // значение M для минимального значения
$shovm2 = shovene ($shovz2); // значение M для максимального значения
if ($shovm1 <= $n and $shovm2 <= $n):
/*------------------------------------------------*/
/* Вычисление случайной составляющей погрешности. */
/*------------------------------------------------*/
$tsdavg = $tsd / sqrt ($n); // среднее квадратическое отклонение среднего $dtrnd = $tan * $tsdavg;
/*---------------------------------*/
/* Вычисление полных погрешностей. */
/*---------------------------------*/
$dtabs = sqrt ($di * $di + $dtrnd * $dtrnd); // абсолютная погрешность $dtrel = round (($dtabs / $tavg) * 100, 2); // относительная погрешность в процентах /*-----------------------------------------*/
/* Запись в файл результатов эксперимента. */
/*-----------------------------------------*/
$res = "Количество опытов: $n\r\n";
$res .= "Продолжительность опытов: ";
for ($i = 0; $i < $n - 1; ++$i):
$res .= $t[$i] . ', ';
endfor;
$res .= $t[$n - 1] . "\r\n";
$res .= "Средняя продолжительность: $tavg\r\n";
$res .= "Относительная погрешность: $dtrel%\r\n";
$f = fopen ($fname, "w"); if ($f):
fputs ($f, "$caption\r\n"); endif;
$tu[] = $tavg;
$pu[] = $dtrel;
echo "See file $fname for results of the experiment\n";
$crit = true;
else:
echo "Shovene criteria!\n";
$crit = false;
endif;
} while (!$crit);
endfor;
/*----------------------------------------------*/
/* Запись в файл общего протокола эксперимента. */
/*----------------------------------------------*/
$f = fopen ($fname, "w"); if ($f):
fputs ($f, "$caption\r\n"); for ($i = 0; $i < count ($tu); ++$i): $tu0 = $tu[$i];
$pu0 = $pu[$i];
fputs ($f, "$tu0 ($pu0%)\r\n"); endfor;
endif;
/*===========================================*/
/* Вычисление выборочного среднего значения. */
/*===========================================*/
function avg ($a)
{
echo "Debug AVG: n = $n\n";
$sa = 0;
for ($i = 0; $i < $n; ++$i):
$sa += $a[$i];
endfor;
return $sa / $n;
}
/*=================================================*/
/* Вычисление среднего квадратического отклонения. */
/*=================================================*/
function stddev ($a, $aavg)
{
$sa = 0;
for ($i = 0; $i < $n; ++$i):
$d = $a[$i] - $aavg;
$sa += $d * $d;
endfor;
return sqrt ($sa / ($n - 1)); }
/*======================================*/
/* Критерий Шовене для отбора промахов. */
/*======================================*/
function shovene ($z)
{
if ($z < 1):
$m = 1;
elseif ($z <= 1.28):
$m = 2;
elseif ($z <= 1.46):
$m = 3;
elseif ($z <= 1.58):
$m = 4;
elseif ($z <= 1.68):
$m = 5;
elseif ($z <= 1.76):
$m = 6;
elseif ($z <= 1.78):
$m = 7;
elseif ($z <= 1.82):
$m = 8;
elseif ($z <= 1.92):
$m = 9;
elseif ($z <= 1.98):
$m = 10;
elseif ($z <= 2.00):
$m = 11;
elseif ($z <= 2.04):
$m = 12;
elseif ($z <= 2.08):
$m = 13;
elseif ($z <= 2.10):
$m = 14;
elseif ($z <= 2.12):
$m = 15;
elseif ($z <= 2.16):
$m = 16;
elseif ($z <= 2.18):
$m = 17;
elseif ($z <= 2.20):
$m = 18;
elseif ($z <= 2.22):
$m = 19;
elseif ($z <= 2.24):
$m = 20;
elseif ($z <= 2.26):
$m = 21;
elseif ($z <= 2.28):
$m = 22;
elseif ($z <= 2.30):
$m = 23;
elseif ($z <= 2.32):
$m = 25;
elseif ($z <= 2.34):
$m = 26;
elseif ($z <= 2.36):
$m = 27;
elseif ($z <= 2.38):
$m = 29;
elseif ($z <= 2.40):
$m = 30;
else:
$m = 999;
endif;
return $m;
}
/*========================================================*/
/* Получение текущего времени с точностью до микросекунд. */
/*========================================================*/
function microtime_float ()
{
return round ((float
)$usec + (float
)$sec, 3); }