※ 引述《eco100 (Maktub)》之銘言:
: 我的問題是這樣的
: 我有一組raw data 這組raw data各有一個start及end值
: 這兩個值的大小範圍 最小從0開始 最大可能會到 1500000
: 我想要用這些raw data 的start值到end值 的「出現次數」做累加
: (除了start及end兩端點外,中間的值也會累加)
: 然後在數線上畫出累加的高度值 畫出來 會像一座座的山峰一樣
: 我的想法是我先宣告一個0到1500000的"0"陣列(raw data 中end可能出現的最大值)
: 然後讀到第一列資料時
: 會有另外一個陣列 將start到end之間的區段 給予 1 的數字 其他為 0
: 然後把這個陣列加到 一開始宣告的 0 陣列中
: 讀到第二列時 又得到某個區段為1的陣列 再加到 一開始的 0 陣列中
: 直到所有raw data 加完為止
: 然後再把最後加完的陣列的每一個元素 當做高度畫在數線上
: 以下是我的程式
: $result = mysql_query("
: select *
: from raw_data
: ");
: $arr = array_fill(0,1500000,'0'); //先宣告一個0陣列
: while($row = mysql_fetch_array($result,MYSQL_BOTH)){
: $start = $row["start"];
: $end = $row["end"];
: $base = array_fill($start,$end-$start+1,'1'); //start到end為1
: $front = array_pad($base,-($end+1),0); //前面為0
: $back = array_pad($front,$size+1,0); //後面為0
: foreach($arr as $key => $value){
: $arr[$key] = $arr[$key] + $back[$key]; //把每一陣列元素相加
: }
: }
: for($i=0;$i<=$size;$i++){ //畫圖
: if($arr[$i]!=0){
: imageline($im,$start_x+$mod*$ratio,$quo*100-$arr[$i]+100,$start_x+$mod*$ratio,$quo*100+100,$green);
: }
: }
: 想請問 這樣的寫法 會不會因為陣列太大造成程式要跑很久?
: 因為我自己測了一下 程式應該沒錯 但是執行時 都跑不太出來 > <
: 是否還有其他 更有效率的寫法?
: 有請高人指點一下 謝謝!
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 219.87.151.40
基本上您的資料量那麼大的時候,
有沒有考慮分段來完成呢?
PHP在預設 MEMORY 下要存入百萬筆資料很容易出現 OUT OF MEMORY,
在計算上也會花很多時間與電腦的資源,
也就是您感覺到程式都跑不太出來的原因。
若真的不拆解,
建議在程式最前面加上
ini_set('memory_limit','1536M');//跑不動或是out of memory時,數字可以加大
set_time_limit(0);//防止程式執行太久 timeout
另外最大值可能會到1500000,
也建議動態開陣列去存取資料,
而不是那麼暴力一次開完到最大值...
SQL的部份建議選取欄位減少使用 * 會快那麼一點點。