2015-01-07 42 views
0

我正在使用php腳本更新產品數據。 雖然消耗的內存是恆定的,每1.000產品所消耗的時間被增加所有的時間:大型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].... 

即使除了讀取線包含CSV數據我的變量i的禁用一切,效果是相同的,除了較低的增加率:

[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)。

我加載我的數據提前與:

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

下一行與檢索:

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

我不知道爲什麼這應該consistantly增加所需要的時間,尤其是當我只是array_shift行而不對其執行任何操作。

我目前的解決方案是將文件拆分爲10.000個文件,這對於包含超過300.000行的文件來說不是一個理想的解決方案,並且必須每天更新。

這將是不錯的,至少明白這裏發生了什麼......

先感謝您的任何提示。

+2

使用一個真正的探查,並找出。 – 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開始。不要將它與枚舉數組的關鍵值混淆,它是純粹內部維護的,並且與關鍵字完全分離,因此您可以執行關聯排序,從而有效地重新組織這些內部位置值。

將新元素添加到數組時,需要給它一個新的序列值。如果您只是將新元素添加到數組的末尾,那麼就像取前一個最高序列值,添加一個元素,並將其指定爲新元素的序列值一樣簡單....一個簡單的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); 

不要嘗試了,覺得PHP的垃圾回收