課題 #997
CSVの読み込み処理を改善する
| Status: | 担当 | Start date: | 06/09/2010 | |
|---|---|---|---|---|
| Priority: | 高め | Due date: | ||
| Assignee: | - | % Done: | 0% |
|
| Category: | その他 | |||
| Target version: | - |
Description
ページ機能において、サーバーキャッシュがない場合に、表示速度が極端に遅くなる。
現在、データベースとして「CSV」を利用する場合、SQLでよくある、「並び替え処理を行った上で、◯番目から◯件を取得する」という要件を満たす為に、一旦全てのデータをメモリに置いてから処理を行っている。
その場合、大量のデータを扱う場合、処理速度が極端に落ちてしまう。
◯番目からという指定がなく、先頭から指定件数を取得するという事であれば、指定件数分の配列を用意してやりロケット鉛筆方式で、メモリ消費量を最小限に抑えて実装可能だが、◯番目からという指定がある場合は??
要件¶
- ランダムにならんだデータを昇順、もしくは降順に並び替えた上で、◯番目から◯件取得できる。(◯には任意の数字が入る)
- データにはCSVの1レコードが入る為、大量件数の場合を考えて、全データをメモリ上にのせずに処理をさせたい。
先頭から指定件数取得するサンプル(ここではただの配列ですが、実際はファイル読み込みとなります)¶
$file = array(1,7,10,8,0,4,6,8,5,2,3,4,3,0,0,11,1000);
$max = 9;
$conditions = '$line >= 9';
$order = 'DESC';
var_dump(readData($file,$max,$conditions,$order));
function readData($file, $max, $conditions, $order = 'ASC'){
$stack=array();
$i=0;
while($i<$max){
$stack[] = null;
$i++;
}
foreach($file as $line){
if($order == 'ASC' && (!is_null($stack[$max-1]) && $stack[$max-1] <= $line)) continue;
if($order == 'DESC' && (!is_null($stack[$max-1]) && $stack[$max-1] >= $line)) continue;
if(!eval('if('.$conditions.') return true;')) continue;
$idx = getIndex($stack, $line, 0, $max-1, $order);
for($i=$max-1; $i>=$idx+1; --$i) {
$stack[$i]=$stack[$i-1];
}
$stack[$idx] = $line;
}
foreach($stack as $key => $value){
if(is_null($value)){
unset($stack[$key]);
}
}
return $stack;
}
function getIndex($stack, $line, $start, $end, $order='ASC'){
if($end < 0){
return 0;
}
$mid = (int)(($start + $end) / 2);
$target = $stack[$mid];
if($target === $line){
return $mid;
}elseif($order=='ASC' && (is_null($target) || $target > $line)){
if(!is_null($stack[$mid-1]) && $stack[$mid-1] < $line){
return $mid;
}else{
return getIndex($stack, $line, $start, $mid-1, $order);
}
}elseif($order=='DESC' && (is_null($target) || $target < $line)){
if(!is_null($stack[$mid-1]) && $stack[$mid-1] > $line){
return $mid;
}else{
return getIndex($stack, $line, $start, $mid-1, $order);
}
} else {
return getIndex($stack, $line, $mid+1, $end, $order);
}
}
History
Updated by ryuring almost 2 years ago
- Assignee set to ryuring
- Target version set to BaserCMS 1.5.8
Updated by ryuring almost 2 years ago
- Target version deleted (
BaserCMS 1.5.8)
Updated by ryuring almost 2 years ago
- Priority changed from 急いで to 高め
Updated by ryuring over 1 year ago
- Assignee deleted (
ryuring)