2013-03-02 3 views
-4

PHP 코드에는 많은 foreach 루프가 포함되어있어 결과는 매우 비참합니다. 실행하는 데 너무 오래 걸립니다.많은 for 루프를 사용하는 PHP 코드 최적화

이에 대한 대안이 있습니까? 나는 모든 제안에 개방적이다.

저는 플래시 기반 클라이언트를 구현하고 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++; 
    } 
} 
+1

Google에서 최적화를 유도하는 데 필요한 코드를 확인해야합니다. Alo 코드 최적화는 [코드 리뷰] (http://codereview.stackexchange.com)의 주제에 대한 자세한 내용 일 수 있습니다. –

+1

질문이 너무 모호합니다. 당신은 우리가이 루프에서 횡단하고있는 데이터의 종류와 실행중인 계산에 대해 아무것도 말하지 않습니다. –

+0

바로 고마워요. 지금 코드를 게시했습니다. – Pranjal

답변

2

음, 쉽게 대답 할 수있는 것이 아닙니다. 예, C++을 알고 있다고 가정하면 C++로 코드를 다시 작성할 수 있습니다. 나는 그 어떤 큰 장애물도 보지 못했다.

원래 geneSet을 C++ 코드로 가져온 다음 $mainArray 및 기타를 나타내는 구조로 구성해야합니다. 배열에 std::vector을 사용하십시오.

이 코드는 실제로 웹 콘텐츠 자체를 생성하지 않으므로 서버에 설치된 C++ 프로그램 호출로이 함수를 대체 할 수 있습니다. C++에서이 함수를 호출하는 기능을 실제로 구현하는 것이 좋습니다. 1M 시간이라면 C++ 코드를 1M 번 호출하는 대신 C++에서 1M 호출을 수행하는 것이 좋습니다.

+0

감사합니다. Mats Peterson PHP와 클라이언트 - 서버 개발에 익숙하지 않습니다. C++에서이 코드를 다시 작성하고 C++ 프로그램에서 호출을 작성하지만 PHP에서 C++ 코드를 호출하는 방법은 명확하지 않습니다. 연결된 목록과 배열을 PHP 코드에서 C++ 클래스로 보내고 배열을 반환하고 배열을 반환하고자합니다. 따라야 할 단계는 무엇입니까? – Pranjal

+0

이 함수를 1M 번 호출하는 데 몇 초가 걸린다고 가정합니다. 따라서 입력 데이터를 파일에 쓰고'exec()'[또는 유사한 PHP 함수]를 사용하여 C++ 프로그램을 실행하고 출력 결과를 파일 (또는'stdout')에 제공하는 것이 합리적 일 것입니다. 수 있습니다 캡처 됨). –

+0

도움 주셔서 감사합니다. 나는 이것을 시도 할 것이다. – Pranjal

관련 문제