2015-01-07 2 views
0

저는 제품 데이터를 업데이트하기 위해 PHP 스크립트를 사용하고 있습니다. 소비 메모리가 일정하지만, 1.000 제품 당 소비되는 시간이 모든 시간 증가 : 내가 CSV 데이터를 포함 내 변수의 라인을 읽기를 제외한 모든 해제하더라도대용량 PHP 5.4 스크립트가 느려짐

[26000 - 439.75 MB/14.822s].......... 
[27000 - 439.25 MB/15.774s].......... 
[28000 - 438.25 MB/15.068s].......... 
[29000 - 437.75 MB/16.317s].......... 
[30000 - 437.25 MB/16.968s].......... 
[31000 - 436.25 MB/17.521s].... 

을, 효과는 동일합니다 낮은 증가율 제외 :

[65000 - 424.75 MB/0.001s].......... 
[66000 - 424.75 MB/0.63s].......... 
[67000 - 424.75 MB/0.716s].......... 
[68000 - 424.75 MB/0.848s].......... 
[69000 - 424.75 MB/0.943s].......... 
[70000 - 424.25 MB/1.126s].......... 
[71000 - 423.5 MB/1.312s].... 

내가 GC 설정 변경 시도 (PHP -dzend.enable_gc = 1, PHP -dzend.enable_gc = 0). 때 특히,이 일관되게 필요한 시간을 증가해야하는 이유를 모르겠어요

$line = array_shift($this->file); 

: 다음 라인으로 검색 한

$this->file = file($file_path); 

:

난과 사전에 내 데이터를로드 아무 조치도 취하지 않고 그냥 array_shift하십시오.

현재 해결 방법은 파일을 10,000 조각으로 분할하는 것입니다.이 방법은 300.000 줄이 넘고 매일 업데이트해야하는 파일에는 바람직하지 않습니다.

적어도 여기에 무슨 이해하는 것이 좋을 것이다 ... 어떤 힌트를 사전에

감사합니다.

+2

실제 프로파일 러를 사용하여 알아 PHP의 가비지 컬렉션 아웃-생각합니다. – PeeHaa

답변

0

array_shift()는 더 작은 세트의 색인을 다시 생성해야하기 때문에 더 많이 사용할수록 기술적으로 빠르게 실행해야합니다.

반환 된 결과와 관련하여 다른 작업을 수행하고 있습니까?

다른 방법으로, 루프 전에 배열을 반대로 생각 할 수 있습니다

$reversed = array_reverse($file); 

그리고 루프

$item = array_pop($reversed); 
0

내부의 마지막 값을 보여주고 사용해야하는 이유를 특정 이유가 있나요 array_shift()?

는 어쩌면 단지 파일을 읽고이 스크립트 실행 속도 것 마감 :

$this->file = file($file_path); 
foreach ($this->file as $line) { 
    // do the thing you need to do 
} 
unset ($this->file); 

또 다른 한가지는 당신이 하나 개의 어레이 ($file)를 읽고 다른 ($line)로 돌려 것으로 보인다는 것이다. 어쩌면 $file 어레이를 그대로 사용하는 것이 가치가 있을지 모르겠다.

정확히 무엇을하고 있는지 잘 모르겠지만 이러한 제안이 도움이 될 수 있기를 바랍니다.

3

배열 매 요소 내부에 유지되는 데이터의 array_shift()

부품의 문제는 그 어레이 내의 요소의 위치를 ​​식별하는 시퀀스 번호이다. 이 값은 사실상 순차적 인 정수로, 첫 번째 요소에 대해 0부터 시작합니다.이것을 열거 형 배열의 키 값과 혼동하지 말고 순전히 내부적으로 유지되며 키와 완전히 분리되므로 이러한 내부 위치 값을 효과적으로 재구성하는 연관성 정렬을 수행 할 수 있습니다.

새 요소를 배열에 추가 할 때 새 시퀀스 값을 지정해야합니다. 배열의 마지막에 새 요소를 추가하는 경우 이전 Higest Sequence 값을 취하여 하나를 추가하고이를 새 요소의 시퀀스 값으로 할당하는 것처럼 간단합니다 .... 간단한 O (1) 활동. 마찬가지로, 마지막 요소를 제거하면 간단히 제거 할 수 있고 다른 모든 요소의 순서는 유효합니다.

그러나 array_unshift()를 사용하여 배열의 시작 부분에 새 요소를 추가하면 0 값이 할당되고 이미 배열에있는 모든 기존 요소의 시퀀스 값이 1 씩 증가해야합니다 따라서 PHP는 내부적으로 O (n) 트랜잭션을 만드는 모든 요소를 ​​트래버스해야합니다. 마찬가지로 array_shift()는 배열에서 첫 번째 요소 인 O (n)을 제거한 후에 나머지 배열 요소에 대한 시퀀스 값을 감소시켜야합니다. 배열이 매우 큰 경우, 이것은 상당한 오버 헤드가 될 수 있습니다.

일반 성능 성능 문제에 대한 대답에서

.... 왜 한 번에 메모리에 전체 파일을 읽고있는? 한 번에 한 줄씩 처리 할 수없는 이유는 무엇입니까?

$fh = fopen('filename.txt', 'r'); 
while (!feof($fh)) { 
    $item = fread($fh); 
    .... processing here 
} 
fclose($fh); 

그리고 시도하지 않는