【问题标题】:Optimizing PHP code that uses a lot of for loops优化使用大量 for 循环的 PHP 代码
【发布时间】:2013-03-02 21:16:50
【问题描述】:

我的 PHP 代码包含很多 foreach 循环,结果绝对是灾难性的。运行时间太长了。

是否有替代方案。我愿意接受所有建议。

我在想可能正在实现一个基于 Flash 的客户端并使用 actionscript 来利用客户端的 CPU 来运行逻辑。

或者有没有办法使用 C/C++ 来处理服务器本身的计算要求高的部分并返回 PHP 的结果。

以下函数被调用了 1,000,000 次。

public function performEnrichmentAnalysis($geneSet) {
    /**
     * $mainArray is a multi dimentional array.
     * EntrezID | Set (0/1) | pValue | rank
     */
    $mainArray = array();
    $finalArray = array();
    $originalGenesScore = 0;
    $randomGenesScore = 0;
    $u = 0;
    $EntrezID = array();
    $Set = array();
    $pValue = array();
    $Rank = array();
    $originalGenes = $geneSet->getGenes();
    $memeberCount = $geneSet->getGeneCount();
    $randomGenes = $this->geneExpressionData->getRandomGenes($memeberCount);
    /**
     * Copy the elements of original and random gene sets to main array.
     */
    foreach ($originalGenes as $key => $value) {
        $pVal = $this->geneExpressionData->getExpressionValue($value);
        $array = array('EntrezID' => $value, 'Set' => 0, 'pValue' => $pVal, 'Rank' => 999);
        array_push($mainArray, $array);
        unset($array);
    }
    foreach ($randomGenes as $key => $value) {
        $pVal = $this->geneExpressionData->getExpressionValue($value);
        $array = array('EntrezID' => $value, 'Set' => 1, 'pValue' => $pVal, 'Rank' => 999);
        array_push($mainArray, $array);
        unset($array);
    }
    /**
     * sort the multi dimentaional array based on p-values
     */
    foreach ($mainArray as $key => $row) {
        $EntrezID[$key] = $row['EntrezID'];
        $Set[$key] = $row['Set'];
        $pValue[$key] = $row['pValue'];
        $Rank[$key] = $row['Rank'];
    }
    array_multisort($pValue, SORT_ASC, $mainArray);

    /**
     * Assign ranks to the genes
     */
    for ($index = 0; $index < count($mainArray); $index++) {
        $row = $mainArray[$index];
        $row['Rank'] = $index + 1;
        $row['Score'] = 0;
        //print_r($row['Rank']);
        array_push($finalArray, $row);
    }

    /**
     * Calculate scores for each gene
     */
    for ($i = 0; $i < count($finalArray); $i++) {
        for ($j = $i + 1; $j < count($finalArray); $j++) {
            if ($finalArray[$j]['Set'] != $finalArray[$i]['Set']) {
                $finalArray[$i]['Score']++;
            }
        }
    }

    /**
     * Calculate score for the entire set and get universal U and z score.
     */
    for ($counter = 0; $counter < count($finalArray); $counter++) {
        if ($finalArray[$counter]['Set'] == 0) {
            $originalGenesScore += $finalArray[$counter]['Score'];
        }
        if ($finalArray[$counter]['Set'] == 1) {
            $randomGenesScore += $finalArray[$counter]['Score'];
        }
    }

    if ($originalGenesScore > $randomGenesScore) {
        $u = $randomGenesScore;
    } else {
        $u = $originalGenesScore;
    }

    $zNumerator = $u - (($memeberCount * $memeberCount) / (2));
    $zDenominatorSquared = ($memeberCount * $memeberCount * ($memeberCount + $memeberCount + 1)) / 12;

    $z = $zNumerator / sqrt($zDenominatorSquared);

    if (abs($z) > 2.303) {
        $this->temp001++;
    } elseif (abs($z) > 1.605) {
        $this->temp005++;
    } else {
        $this->tempRemaining++;
    }
}

【问题讨论】:

  • 如果您希望我们帮助您优化,我们需要查看代码。 Alo 代码优化可能在code review 上更受关注
  • 我觉得你的问题有点太模糊了。您没有告诉我们任何有关您在这些循环中遍历的数据类型以及您正在运行的计算的任何信息。
  • 好的,谢谢。我现在发布了代码。
  • 我不想使用 PHP,我正在寻找替代方案。但它必须是基于网络的应用程序,所以还有其他选择吗?
  • PHP 是错误的技术来做到这一点。用 C/C++ 编写。

标签: php c++ c actionscript-3 optimization


【解决方案1】:

嗯,这不是一个可以轻易回答的问题。是的,假设你知道 C++,代码可以用 C++ 重写。我认为这没有任何重大障碍。

您必须想出一种方法将您的原始 geneSet 转换为 C++ 代码,然后构造一个结构来表示您的 $mainArray 和其他 .为您的阵列使用std::vector

由于此代码本身实际上并没有生成任何网络内容,因此您可以很容易地将函数替换为对安装在服务器上的 C++ 程序的调用。我建议你实际上在 C++ 中实现 CALLS 这个函数的功能,因为如果这被调用了 1M 次,那么你最好在 C++ 中进行 1M 次调用,而不是调用一段 C++ 代码 1M 次。

【讨论】:

  • 谢谢 Mats Peterson 我是 PHP 和客户端-服务器开发的新手。我将用 C++ 重写它,并从 C++ 程序中进行调用,但我不清楚如何从 PHP 调用 C++ 代码。我想将一个链表和一个数组从 PHP 代码发送到 C++ 类,该类将起作用,然后返回一个数组。我应该遵循哪些步骤?
  • 我假设调用这个函数 1M 次需要几秒钟,对吧?因此,将输入数据写入文件,使用exec() [或一些类似的 PHP 函数] 执行 C++ 程序,并在文件中提供输出结果(或在 stdout 上可以是捕获)。
  • 感谢您的帮助。我会试试这个。
猜你喜欢
  • 1970-01-01
  • 2011-10-12
  • 2019-11-10
  • 1970-01-01
  • 2014-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多