Php 优化基极转换环路

Php 优化基极转换环路,php,algorithm,optimization,base-conversion,Php,Algorithm,Optimization,Base Conversion,所以,对于我的密码学库,我有一个我经常使用的。这并不是世界上最有效的方法,但它对所有输入范围都很有效 大部分工作由回调循环完成: $callback = function($source, $src, $dst) { $div = array(); $remainder = 0; foreach ($source as $n) { $e = floor(($n + $remainder *

所以,对于我的密码学库,我有一个我经常使用的。这并不是世界上最有效的方法,但它对所有输入范围都很有效

大部分工作由回调循环完成:

    $callback = function($source, $src, $dst) {
        $div       = array();
        $remainder = 0;
        foreach ($source as $n) {
            $e         = floor(($n + $remainder * $src) / $dst);
            $remainder = ($n + $remainder * $src) % $dst;
            if ($div || $e) {
                $div[] = $e;
            }
        }
        return array(
            $div,
            $remainder
        );
    };
    while ($source) {
        list ($source, $remainder) = $callback($source, $srcBase, $dstBase);
        $result[]                  = $remainder;
    }
基本上,它接受
$srcBase
中的数字数组,并将其转换为
$dstBase
中的数字数组。因此,一个示例输入是
array(1,1),2,10
,其结果是
array(3)
。另一个例子是
数组(1,0,0),256,10
,它将给出
数组(1,6,7,7,2,1,6)
(数组的每个元素都是
$dstBase
中的单个“数字”)

我现在面临的问题是,如果我向它提供2kb的数据,运行几乎需要10秒。因此,我开始对它进行优化。到目前为止,我用这个递归循环替换整个结构,使它只需4秒左右:

    while ($source) {
        $div       = array();
        $remainder = 0;
        foreach ($source as $n) {
            $dividend  = $n + $remainder * $srcBase;
            $res       = (int) ($dividend / $dstBase);
            $remainder = $dividend % $dstBase;
            if ($div || $res) {
                $div[] = $res;
            }
        }
        $result[] = $remainder;
        $source   = $div;
    }
我面临的问题是如何进一步优化它(如果有可能的话)。我认为问题在于大输入所需的迭代次数(对于2000个元素的数组,从基256到基10,总共需要4815076次迭代)


有什么想法吗?

99.9%执行此脚本所需的时间来自于对输入进行迭代的内在需求。由于foreach中的代码非常基本,因此减少执行时间的唯一方法是减少迭代次数。如果这不可能,则您拥有此函数的最有效版本

我不确定,但是

$dividend  = $remainder * $srcBase + $n;

可以快一点…

是的,可以优化一点:

$source_count = count($source);
while ($source) {
    $remainder = $i = 0;
    foreach ($source AS &$n) {
        $dividend = $n + $remainder * $srcBase;
        $remainder = $dividend % $dstBase;
        $res = ($dividend - $remainder) / $dstBase;
        if ($i || $res)
            $source[$i++] = $res;
    }
    for ($j=$i; $j < $source_count; $j++)
        unset($source[$i]);
    $source_count=$i;
    $result[] = $remainder;
}
$source\u count=count($source);
while($来源){
$余数=$i=0;
foreach($sourceas&$n){
$股息=$n+$余数*$srcBase;
$余数=$股息%$dstBase;
$res=($股息-$余款)/$dstBase;
如果($i | |$res)
$source[$i++]=$res;
}
对于($j=$i;$j<$source\u count;$j++)
未设置($source[$i]);
$source_count=$i;
$result[]=$resident;
}
甚至更快,但更模糊:

$source_count = count($source);
while ($source) {
    $remainder = $i = 0;
    foreach ($source AS &$n) {
        if (($res = ($dividend - ($remainder = ($dividend = $n + $remainder * $srcBase) % $dstBase)) / $dstBase) || $i)
            $source[$i++] = $res;
    }
    for ($j=$i; $j < $source_count; $j++)
        unset($source[$i]);
    $source_count=$i;
    $result[] = $remainder;
}
$source\u count=count($source);
while($来源){
$余数=$i=0;
foreach($sourceas&$n){
如果($res=($distribution-($distribution=($distribution=$n+$restribution*$srcBase)%$dstBase))/$dstBase)|$i)
$source[$i++]=$res;
}
对于($j=$i;$j<$source\u count;$j++)
未设置($source[$i]);
$source_count=$i;
$result[]=$resident;
}
您将获得一些内存和CPU使用率的减少,这是更有趣的,但cource不可读(:)


但就我个人而言,我认为你做得不对。我认为你应该使用一些快速C代码来完成这类任务(通过使用系统调用或编写/安装现有的PHP模块).我认为Hip Hop PHP、Zend Optimized等代码优化器/编译器在这种情况下可以显著提高性能。

你认为如何?为什么会更快?曾经阅读过内部的数学计算方法,但我不确定。这是关于先阅读整个函数,但当使用*时,第一个PHP可以从数学开始读取下一个令牌…它仍然需要查看下一个令牌,因为还有其他的运算符。因此它不会有任何区别(如果有区别,也不会有大的区别),最多纳秒…这是我的观点。不是我如何优化
$x%$y
,而是如何改变算法以减少必要的迭代。。。