PHP dosyası yazma optimizasyon

4 Cevap php

EDIT: Optimization results at end of this question!

çok sayıda ... "else if" name adlı başka bir klasöre yeni değiştirilmiş bir dosya yazmak ne zaman açıldığı gibi sonra merhaba, ben ilk belirli bir klasördeki dosyaları tarayabilir ve sonra satır her dosya satır okumak için aşağıdaki kodu var ve .

problem satır bir dosya satır yazı çok slooooow gibi görünüyor olmasıdır. Varsayılan 60 saniye sınırı sadece, böylece dosyalar 25 için yeterli olacak, ya olacak. Dosya boyutları 10k 350k değişir.

Daha hızlı çalışan yapmak için kodu optimize etmek için herhangi bir yol. O, çizgilerle satır okumak bir diziye her çizgiler koymak ve sonra (satır okuma / yazma ile hat vs) yeni bir metin dosyası içine bütün bir dizi yazmak daha iyidir. Eğer durum bu ise, bu uygulamada nasıl yapılır.

thanks in advance ----- The code follows -----

<?php

function scandir_recursive($path)    {
...
...
}



$fileselection = scandir_recursive('HH_new');
foreach ($fileselection as $extractedArray) {
$tableName = basename($extractedArray); // Table name
$fileLines=file($extractedArray);
    foreach ($fileLines as $line) {
    		if(preg_match('/\(all-in\)/i' , $line)) {
    			$line = stristr($line, ' (all-in)', true) .', and is all in';
    			$allin = ', and is all in';
    		}
    		else {
    			$allin = '';
    		}
    		if(preg_match('/posts the small blind of \$[\d\.]+/i' , $line)) {
    			$player = stristr($line, ' posts ', true);
    			$betValue = substr(stristr($line, '$'), 1);
    			$bettingMatrix[$player]['betTotal'] = $betValue;
    		}
    		else if(preg_match('/posts the big blind of \$[\d\.]+/i' , $line)) {
    			$player = stristr($line, ' posts ', true);
    			$betValue = substr(stristr($line, '$'), 1);
    			$bettingMatrix[$player]['betTotal'] = $betValue;
    		}
    		else if(preg_match('/\S+ raises /i' , $line)) {
    			$player = stristr($line, ' raises ', true);
    			$betValue = substr(strstr($line, '$'), 1);
    			$bettingMatrix[$player]['betTotal'] = $betValue; //total bet this hand (shortcut)
    		}
    		else if(preg_match('/\S+ bets /i' , $line)) {
    			$player = stristr($line, ' bets ', true);
    			$betValue = substr(strstr($line, '$'), 1);
    			$bettingMatrix[$player]['betTotal'] = $betValue; //total bet this hand (shortcut)
    		}
    		else if(preg_match('/\S+ calls /i' , $line)) {
    			$player = stristr($line, ' calls ', true);
    			$betValue = substr(stristr($line, '$'), 1);
    			$callValue = $betValue - $bettingMatrix[$player]['betTotal']; //actual amount called
    			$bettingMatrix[$player]['betTotal'] = $betValue;
    			$line = stristr($line, '$', true)."\$".$callValue.$allin;
    			$allin = '';
    		}
    		else if(preg_match('/(\*\*\* (Flop|Turn|River))|(Full Tilt Poker)/i' , $line)) {
    			unset($bettingMatrix); //zero $betValue
    		}
    		else if(preg_match('/\*\*\* FLOP \*\*\*/i' , $line)) {
    			$flop = substr(stristr($line, '['), 0, -2);
    			$line = '*** FLOP *** '. $flop;
    		}
    		else if(preg_match('/\*\*\* TURN \*\*\*/i' , $line)) {
    			$turn = substr(stristr($line, '['), 0, -2);
    			$line = '*** TURN *** '. $flop .' '. $turn;
    		}
    		else if(preg_match('/\*\*\* RIVER \*\*\*/i' , $line)) {
    			$river = substr(stristr($line, '['), 0, -2);
    			$line = '*** RIVER *** '. substr($flop, 0, -1) .' '. substr($turn, 1) .' '. $river;
    		}
    		else {
    		}
    	$ourFileHandle = fopen("HH_newest/".$tableName.".txt", 'a') or die("can't open file");
    	fwrite($ourFileHandle, $line);
    	fclose($ourFileHandle);
    }
}
?>


EDIT: Here's VERY interesting results after rewriting the code based on tips everyone here gave me.

60 metin dosyaları, 5,8 MB toplam

Tüm optimizasyon sonra (döngü öncesi gebelik-> strpos / strstr & $ kolu değişti): 4 sec.

Yukarıdaki gibi AMA değişti strpos / strstr -> stripos / stristr: 8 sec.

Yukarıdaki gibi AMA stripos / stristr değişti -> gebelik: 12 sec.

45/60 files after 180sec run limit: Yukarıdaki gibi AMA döngü içinde fopen değişti

İşte tam script:

$fileselection = scandir_recursive('HH_new');
foreach ($fileselection as $extractedArray) {
    $tableName = basename($extractedArray); // Table name
    $handle			= fopen($extractedArray, 'r');
    $ourFileHandle	= fopen("HH_newest/".$tableName.".txt", 'a') or die("can't open file");
    while ($line = fgets($handle)) {
    		if (FALSE !== strpos($line, '(all-in)')) {
    			$line = strstr($line, ' (all-in)', true) .", and is all in\r\n";
    			$allin = ', and is all in';
    		} else {
    			$allin = '';
    		}
    		if (FALSE !== strpos($line, ' posts the small blind of $')) {
    			$player = strstr($line, ' posts ', true);
    			$betValue = substr(strstr($line, '$'), 1);
    			$bettingMatrix[$player]['betTotal'] = $betValue;
    		}
    		else if (FALSE !== strpos($line, ' posts the big blind of $')) {
    			$player = strstr($line, ' posts ', true);
    			$betValue = substr(strstr($line, '$'), 1);
    			$bettingMatrix[$player]['betTotal'] = $betValue;
    		}
    		else if (FALSE !== strpos($line, ' posts $')) {
    			$player = strstr($line, ' posts ', true);
    			$betValue = substr(strstr($line, '$'), 1);
    			$bettingMatrix[$player]['betTotal'] += $betValue;
    		}
    		else if (FALSE !== strpos($line, ' raises to $')) {
    			$player = strstr($line, ' raises ', true);
    			$betValue = substr(strstr($line, '$'), 1);
    			$betMade = $betValue - $bettingMatrix[$player]['betTotal']; //actual amount raised by
    			$bettingMatrix[$player]['betTotal'] = $betValue; //$line contains total bet this hand (shortcut)
    		}
    		else if (FALSE !== strpos($line, ' bets $')) {
    			$player = strstr($line, ' bets ', true);
    			$betValue = substr(strstr($line, '$'), 1);
    			$betMade = $betValue - $bettingMatrix[$player]['betTotal']; //actual amount raised by
    			$bettingMatrix[$player]['betTotal'] = $betValue; //$line contains total bet this hand (shortcut)
    		}
    		else if (FALSE !== strpos($line, ' calls $')) {
    			$player = strstr($line, ' calls ', true);
    			$betValue = substr(strstr($line, '$'), 1);
    			$callValue = $betValue - $bettingMatrix[$player]['betTotal']; //actual amount called
    			$bettingMatrix[$player]['betTotal'] = $betValue;
    			$line = strstr($line, '$', true)."\$".$callValue.$allin. "\r\n";
    			$allin = '';
    		}
    		else if (FALSE !== strpos($line, '*** FLOP ***')) {
    			$flop = substr(strstr($line, '['), 0, -2);
    			unset($bettingMatrix); //zero $betValue
    		}
    		else if (FALSE !== strpos($line, '*** TURN ***')) {
    			$turn = substr(strstr($line, '['), 0, -2);
    			$line = '*** TURN *** '.$flop.' '.$turn."\r\n";
    			unset($bettingMatrix); //zero $betValue
    		}
    		else if (FALSE !== strpos($line, '*** RIVER ***')) {
    			$river = substr(strstr($line, '['), 0, -2);
    			$line = '*** RIVER *** '. substr($flop, 0, -1) .' '. substr($turn, 1) .' '. $river."\r\n";
    			unset($bettingMatrix); //zero $betValue
    		}
    		else if (FALSE !== strpos($line, 'Full Tilt Poker')) {
    			unset($bettingMatrix); //zero $betValue
    		}
    		else {
    		}
    	fwrite($ourFileHandle, $line);
    }
    fclose($handle);
    fclose($ourFileHandle);
}

4 Cevap

i döngü içinde dosyayı kapatma / açıyoruz, çünkü bu, foreach önce ve fclose ondan sonra) (fopen hareket deneyin olduğunu düşünüyorum

Ben yazma dosyası burada performans sorunu olduğunu sanmıyorum. Sen üzerine ten düzenli ifadeler koşuyoruz everything!

strpos alt dizeleri bulmak için dize gibi yöntemler kullanarak şeyler hızlandırmak olabilir.

Duyarsız durumda stripos () - - Sen strpos() veya benzer şekilde değiştirmek eğer düzenli ifade ile uzak yapıyor, size en performans artışı verecek bir hız artışı göreceksiniz.

Test bulundu dize 0 konumunda olabilir beri, '!== false' olması gerekir Örneğin, ilk test case () olabilir.:

if(stripos($line, '(all-in)') !== false) {
    //generate output
}

Ayrıca bazı performans artışı verebilir yerine tek seferde tüm dosyayı okuma fgets () kullanarak bulabilirsiniz (ama daha bir hafıza sorunu var). Ve başkaları tarafından belirtildiği gibi, yalnızca döngü içinde dosyaya yazma açmayın ve kapatın.

Burada biraz yardımcı olmalıdır birkaç küçük değişiklik ile kod

  1. fgets() için file() geçti. Bu dosyadan bellek yerine her satırı bir seferde sadece tek bir hat yük olacaktır.
  2. preg_match() stripos() uygulanabilirse aramalarınızı değiştirildi. Bir nebze daha hızlı olmalı
  3. Dış döngü içine $ourFileHandle açılış / kapanış taşındı. Bu significantly dosya sistemine istatistik çağrıların sayısını azaltacak ve büyük ölçüde hızlandırmak gerekir.

If .. else o canavarca yapılabilir ama başka Soer (ya da) için bu kadar bırakacağım diğer optimizasyonlar bir sürü muhtemelen vardır

$fileselection = scandir_recursive('HH_new');
foreach ($fileselection as $extractedArray)
{ 
  $tableName     = basename( $extractedArray ); // Table name
  $handle        = fopen( $extractedArray, 'r' );
  $ourFileHandle = fopen("HH_newest/".$tableName.".txt", 'a') or die("can't open file");

  while ( $line = fgets( $handle ) )
  {
    if ( false !== stripos( $line, '(all-in)' ) )
    {
      $line = stristr($line, ' (all-in)', true) .', and is all in';
      $allin = ', and is all in';
    } else {
      $allin = '';
    }
    if ( preg_match('/posts the small blind of \$[\d\.]+/i' , $line ) )
    {
            $player = stristr($line, ' posts ', true);
            $betValue = substr(stristr($line, '$'), 1);
            $bettingMatrix[$player]['betTotal'] = $betValue;
    }
    else if(preg_match('/posts the big blind of \$[\d\.]+/i' , $line)) {
            $player = stristr($line, ' posts ', true);
            $betValue = substr(stristr($line, '$'), 1);
            $bettingMatrix[$player]['betTotal'] = $betValue;
    }
    else if(preg_match('/\S+ raises /i' , $line)) {
            $player = stristr($line, ' raises ', true);
            $betValue = substr(strstr($line, '$'), 1);
            $bettingMatrix[$player]['betTotal'] = $betValue; //total bet this hand (shortcut)
    }
    else if(preg_match('/\S+ bets /i' , $line)) {
            $player = stristr($line, ' bets ', true);
            $betValue = substr(strstr($line, '$'), 1);
            $bettingMatrix[$player]['betTotal'] = $betValue; //total bet this hand (shortcut)
    }
    else if(preg_match('/\S+ calls /i' , $line)) {
            $player = stristr($line, ' calls ', true);
            $betValue = substr(stristr($line, '$'), 1);
            $callValue = $betValue - $bettingMatrix[$player]['betTotal']; //actual amount called
            $bettingMatrix[$player]['betTotal'] = $betValue;
            $line = stristr($line, '$', true)."\$".$callValue.$allin;
            $allin = '';
    }
    else if(preg_match('/(\*\*\* (Flop|Turn|River))|(Full Tilt Poker)/i' , $line)) {
            unset($bettingMatrix); //zero $betValue
    }
    else if ( FALSE !== stripos( $line, '*** FLOP ***' ) )
    {
            $flop = substr(stristr($line, '['), 0, -2);
            $line = '*** FLOP *** '. $flop;
    }
    else if ( FALSE !== stripos( $line, '*** TURN ***' ) )
    {
            $turn = substr(stristr($line, '['), 0, -2);
            $line = '*** TURN *** '. $flop .' '. $turn;
    }
    else if ( FALSE !== stripos( $line, '*** RIVER ***' ) )
    {
            $river = substr(stristr($line, '['), 0, -2);
            $line = '*** RIVER *** '. substr($flop, 0, -1) .' '. substr($turn, 1) .' '. $river;
    }
    else {
    }
    fwrite($ourFileHandle, $line);
  }
  fclose( $handle );
  fclose( $ourFileHandle );
}