Чтобы немного оптимизировать это, нам нужно помнить, что PHP имеет большие накладные расходы при разборе кода, так как он не компилируется, поэтому нам нужно сделать для этого как можно больше работы.Вы всегда должны профилировать свой чувствительный к процессору / памяти код с помощью xdebug + KCachegrind (например), чтобы увидеть, где PHP тратит большую часть своего времени.С вашим кодом только 12% тратится на вычисления функций gmp_ *, большую часть времени тратится на разбор кода.
На моем ноутбуке (это довольно медленно) мой код выполняется 2,4 с вместо 3,5 с для вашегокод, но для большей степени разница должна быть более заметной (например, 19 мощность дает 19 против 28 секунд).Это не много, но немного.
Я оставил комментарии внутри кода, но если у вас есть вопросы - не стесняйтесь спрашивать.Я использовал создание функции, чтобы заменить этот цикл 'for ($ i = 1; $ i <$ n; $ i ++)' внутри вашего основного цикла. </p>
Кроме того, я думаю, вам следует изменить тип переменной $ periodв GMP (и $ period ++ to gmp_ * function), поскольку она может быть больше максимального целого числа в вашей системе.
function getPeriod() {
$polynoms = array(16, 14, 13, 11);
$highest = $polynoms[0];
$input = $highest - 1;
//Delete first element of array - we don't need it anyway
array_shift($polynoms);
$polynoms_count = count($polynoms);
//You always repeat gmp_pow(2, $input) and it's result is constant,
//so better precalculate it once.
$input_pow = gmp_pow(2, $input);
//Start function creation.
//If you don't use PHP accelerators, then shorter variable names
//work slightly faster, so I replaced some of names
//$perion->$r,$bit -> $b, $lfsr -> $l, $polynoms -> $p
$function_str = '$r=0;';
$function_str .= 'do{';
//Now we need to get rid of your loop inside loop, we can generate
//static functions chain to replace it.
//Also, PHP parses all PHP tokens, even ';' and it takes some time,
//So, we should write as much one-liners as we can.
$function_str .= '$b=gmp_xor($b=$l';
foreach ($polynoms AS $id => &$polynom) {
//You always repeat gmp_pow(2, $polynoms[$i]) and it's result is constant,
//so better precalculate it once.
$polynom = gmp_pow(2, $highest - $polynom);
//We create our functions chain here
if ($id < $polynoms_count - 1) {
$function_str.=',gmp_xor(gmp_div_q($l, $p[' . $id . '])';
} else {
$function_str.=',gmp_div_q($l, $p[' . $id . '])';
}
}
//Close all brackets
$function_str.=str_repeat(')', $polynoms_count);
//I don't know how to optimize the following, so I left it without change
$function_str.=';';
$function_str.='$l = gmp_or((gmp_div_q($l, 2)), (gmp_mul(gmp_and($b, 1), $i_p)));';
$function_str.='$r++;';
$function_str.='} while (gmp_cmp($l, 0x1));';
$function_str.='return $r;';
//Now, create our funciton
$function = create_function('$l,$p,$i_p', $function_str);
//Set begining states
$lfsr = 0x1;
$lfsr = gmp_init($lfsr, 16);
//Run function
$period = $function($lfsr, $polynoms, $input_pow);
//Use result
echo '<br />period = ' . $period;
return $period;
}