优化此功能

时间:2012-03-05 13:22:02

标签: php optimization micro-optimization

我有一个脚本可以调用这个函数超过100k次,所以无论如何我都在寻找更多的性能。

您能否建议使用优化或替代方法来计算PHP中的标准偏差?

function calcStandardDev($samples){


    $sample_count = count($samples);

    for ($current_sample = 0; $sample_count > $current_sample; ++$current_sample) $sample_square[$current_sample] = pow($samples[$current_sample], 2);

    return sqrt(array_sum($sample_square) / $sample_count - pow((array_sum($samples) / $sample_count), 2));

}

3 个答案:

答案 0 :(得分:1)

$samples[$current_sample] * $samples[$current_sample]

会比

更快
pow($samples[$current_sample], 2)

因为它没有函数调用的开销。

然后你也可以简化

pow((array_sum($samples) / $sample_count), 2));

防止再次调用pow()函数

为避免array_sum($ samples)因更改而被调用两次,计算一次并在循环之前存储到var,然后只引用公式中的var。

修改

function calcStandardDev($samples){
    $sample_count = count($samples);
    $sumSamples = array_sum($samples);

    for ($current_sample = 0; $sample_count > $current_sample; ++$current_sample)
        $sample_square[$current_sample] = $samples[$current_sample] * $samples[$current_sample];


    return sqrt(array_sum($sample_square) / $sample_count - ( ($sumSamples / $sample_count) *
                                                              ($sumSamples / $sample_count)
                                                            )
               );

}

答案 1 :(得分:0)

通过自己计算相应的值来替换两个对array_sum的调用。这样你只需要一次遍历阵列而不是三次。

function calcStandardDev($samples){

    $sample_count = count($samples);
    $sum = 0;
    $sum_sqaure = 0;

    for ($current_sample = 0; $sample_count > $current_sample; ++$current_sample) {
        $sum_square += pow($samples[$current_sample], 2);
        $sum += $samples[$current_sample];
    }

    return sqrt( $sum_square / $sample_count - pow( $sum / $sample_count, 2));
}

答案 2 :(得分:0)

forefe by referance比for,你已经有一个循环,你可以在这个循环中计算“sum”。和$ x * $ x比pow($ x,2)快得多; 有一些功能比较。希望能帮到你。

您的函数microtime = ~0.526

第二功能 = ~0.290

  <?php
    function calcStandardDev($samples)
    {


        $sample_count = count($samples);

        for ($current_sample = 0; $sample_count > $current_sample; ++$current_sample) 
            $sample_square[$current_sample] = pow($samples[$current_sample], 2);

        return sqrt(array_sum($sample_square) / $sample_count - pow((array_sum($samples) / $sample_count), 2));

    }

    function calcStandardDev2($samples)
    {
        $sample_count = count($samples);

        $sum_sample_square  = 0;
        $sum_sample         = 0;

        foreach ($samples as &$sample) 
        {
            $sum_sample         += $sample;
            $sum_sample_square  += $sample * $sample; 
        }

        return sqrt($sum_sample_square / $sample_count - pow($sum_sample / $sample_count,2));

    }

     function calcStandardDev3($samples)
    {
        $sample_count = count($samples);

        $sum_sample_square  = 0;
        $sum_sample         = 0;

        foreach ($samples as &$sample) 
        {
            $sum_sample         += $sample;
            $sum_sample_square  += pow($sample ,2); 
        }

        return sqrt($sum_sample_square / $sample_count - pow($sum_sample  / $sample_count,2));

    }

    echo "<pre>";
    $samples = range(2,100000);

    $start  = microtime(true);
    echo calcStandardDev($samples)."\r\n";
    $end  = microtime(true);
    echo $end - $start ."\r\n";  
    echo "-------\r\n";

    $start  = microtime(true);
    echo calcStandardDev2($samples)."\r\n";
    $end  = microtime(true);
    echo $end - $start."\r\n";
    echo "-------\r\n";

    $start  = microtime(true);
    echo calcStandardDev3($samples)."\r\n";
    $end  = microtime(true);
    echo $end - $start;
    echo "-------\r\n";
?>