Получение строки по номеру в большом массиве
Стоит такая задача:
Есть файл, в котором дано 500 000 строк. Получить строку из такого файла имея её номер.
Например в файле 4 строки:
Вася
Петя
Чтото
Както
...
Нужно получить строку под номером 4 - "Както".
Всё бы ничего, казалось бы:
Код:
$num=4;
$word=file(PATH.'/file.txt');
print( trim($word[($num-1)]) );
$word=file(PATH.'/file.txt');
print( trim($word[($num-1)]) );
Но если массив на пол миллиона строк и скрипт будет вызываться очень часто памяти сервера нехватет так как скрипт слишком ресурсоёмкий. Решение не оптимально. Функция file записывает весь файл в масиив...Нужно как то читать файл и постараться обратиться к нужной строке. Возникли идеи про fgets. Читаем файл, подсчитываем строки, на каждой итерации и смотрим номер:
Код:
$num=20000;
$sch=1;
$f=fopen(path.'/file.txt', 'r');
$string='';
while(!feof($f))
{
$string=fgets($f);
if($sch==$num) break;
$sc++;
}
echo $string;
$sch=1;
$f=fopen(path.'/file.txt', 'r');
$string='';
while(!feof($f))
{
$string=fgets($f);
if($sch==$num) break;
$sc++;
}
echo $string;
Но этот вариант тоже думаю ресурсоёмкий
Может кто знает методы поиска оптимальные для данной задчи.
Про БД не советуйте - задача именно с файлом.
Хотя, такой вариант даже медленней может быть.
Вам я могу посоветовать только одно - поиспользовать профайлер, или просто заюзать microtime(true) для засечения времени выполнения скирптов. А там уже можно будет сделать выводы.
Цитата:
Но этот вариант тоже думаю ресурсоёмкий
Что заставляет вас так думать? Какие ресурсы на ваш взгляд здесь потребляются в неуёмных количествах?
Цитата: vasa_c
Какие ресурсы на ваш взгляд здесь потребляются в неуёмных количествах?
Нефть, золото, цинк...
Какие еще могут быть ресурсы у компьютера? Процессорное время и оперативная память
Цитата: vasa_c
Что заставляет вас так думать? Какие ресурсы на ваш взгляд здесь потребляются в неуёмных количествах?
Вы конечно меня извините, но Вы представляете что такое выполнение этого скрипта на сервере с большой посещаемостью ? когда в секунду выполняется несколько раз...
построить его примерно таким способом
Код:
$content = '';
$start=0;
$len=0;
$f=fopen(path.'/file.txt', 'r');
$bst=0;
$ben=0;
if($f)
{
while (!feof($$f))
{
$buffer = fgets($f, 4096);
$pos=strpos("\n",$buffer);
while($pos!==false)
{
$len=$bst+$pos-$start;//конец текущей строки
$content .= sprintf('%08x',$start).sprintf('%08x',$len);
$start=$len;
$pos=strpos("\n",$buffer,$pos+1);
}
$ben=$bst+strlen($buffer);
$bst=$ben;
}
$len=$ben-$start;//конец последней строки - конец файла
$content .= sprintf('%08x',$start).sprintf('%08x',$len);
fclose($handle);
file_put_contents(path.'/index',$content);
}
$start=0;
$len=0;
$f=fopen(path.'/file.txt', 'r');
$bst=0;
$ben=0;
if($f)
{
while (!feof($$f))
{
$buffer = fgets($f, 4096);
$pos=strpos("\n",$buffer);
while($pos!==false)
{
$len=$bst+$pos-$start;//конец текущей строки
$content .= sprintf('%08x',$start).sprintf('%08x',$len);
$start=$len;
$pos=strpos("\n",$buffer,$pos+1);
}
$ben=$bst+strlen($buffer);
$bst=$ben;
}
$len=$ben-$start;//конец последней строки - конец файла
$content .= sprintf('%08x',$start).sprintf('%08x',$len);
fclose($handle);
file_put_contents(path.'/index',$content);
}
и в результате получить строчку с номером $n
Код:
$start=0;
$len=0;
$string='';
$f=fopen(path.'/index', 'r');
if($f)
{
fseek(16*$n);
$buffer = fgets($f, 16);
$start=hexdec(substr($buffer,0,8));
$len=hexdec(substr($buffer,8,8));
fclose($handle);
}
$f=null;
if($len>0)$f=fopen(path.'/file.txt', 'r');
if($f)
{
fseek($start);
$string = fgets($f, $len);
fclose($handle);
}
echo $string;
$len=0;
$string='';
$f=fopen(path.'/index', 'r');
if($f)
{
fseek(16*$n);
$buffer = fgets($f, 16);
$start=hexdec(substr($buffer,0,8));
$len=hexdec(substr($buffer,8,8));
fclose($handle);
}
$f=null;
if($len>0)$f=fopen(path.'/file.txt', 'r');
if($f)
{
fseek($start);
$string = fgets($f, $len);
fclose($handle);
}
echo $string;
Цитата:
Какие еще могут быть ресурсы у компьютера? Процессорное время и оперативная память
И где они здесь потребляются?
Цитата:
Вы конечно меня извините, но Вы представляете что такое выполнение этого скрипта на сервере с большой посещаемостью ? когда в секунду выполняется несколько раз...
На сервере с большой посещаемостью ваша задача в общем виде имеет только одно решение - изменение структуры хранения данных.
Приложив немного сообразительности можно спокойно обойти ограничения max_execution_time использовав логинование и/или распаралеливание.