Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Получение строки по номеру в большом массиве

42K
11 ноября 2009 года
Roin
17 / / 22.04.2009
День добрый.
Стоит такая задача:
Есть файл, в котором дано 500 000 строк. Получить строку из такого файла имея её номер.
Например в файле 4 строки:
Вася
Петя
Чтото
Както

...
Нужно получить строку под номером 4 - "Както".
Всё бы ничего, казалось бы:
 
Код:
$num=4;
$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;

Но этот вариант тоже думаю ресурсоёмкий
Может кто знает методы поиска оптимальные для данной задчи.
Про БД не советуйте - задача именно с файлом.
244
11 ноября 2009 года
UAS
2.0K / / 19.07.2006
Если честно, не знаю что быстрее. Может, считывать целиком не строки, а посимвольно, т.е. считать появления \n.
Хотя, такой вариант даже медленней может быть.

Вам я могу посоветовать только одно - поиспользовать профайлер, или просто заюзать microtime(true) для засечения времени выполнения скирптов. А там уже можно будет сделать выводы.
7.9K
11 ноября 2009 года
vasa_c
191 / / 05.04.2007
Цитата:
Но этот вариант тоже думаю ресурсоёмкий


Что заставляет вас так думать? Какие ресурсы на ваш взгляд здесь потребляются в неуёмных количествах?

13
11 ноября 2009 года
RussianSpy
3.0K / / 04.07.2006
Цитата: vasa_c
Какие ресурсы на ваш взгляд здесь потребляются в неуёмных количествах?


Нефть, золото, цинк...

Какие еще могут быть ресурсы у компьютера? Процессорное время и оперативная память

42K
12 ноября 2009 года
Roin
17 / / 22.04.2009
Цитата: vasa_c
Что заставляет вас так думать? Какие ресурсы на ваш взгляд здесь потребляются в неуёмных количествах?



Вы конечно меня извините, но Вы представляете что такое выполнение этого скрипта на сервере с большой посещаемостью ? когда в секунду выполняется несколько раз...

18K
12 ноября 2009 года
max_br
34 / / 10.12.2006
если файл меняется нечасто то, помоему, лутше всего обзавестись индексным файлом.
построить его примерно таким способом
Код:
$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;
7.9K
12 ноября 2009 года
vasa_c
191 / / 05.04.2007
Цитата:
Какие еще могут быть ресурсы у компьютера? Процессорное время и оперативная память


И где они здесь потребляются?

Цитата:
Вы конечно меня извините, но Вы представляете что такое выполнение этого скрипта на сервере с большой посещаемостью ? когда в секунду выполняется несколько раз...


На сервере с большой посещаемостью ваша задача в общем виде имеет только одно решение - изменение структуры хранения данных.

12
14 ноября 2009 года
alekciy
3.0K / / 13.12.2005
max_br абсолютно прав. Все проблемы решает fseek.
Приложив немного сообразительности можно спокойно обойти ограничения max_execution_time использовав логинование и/или распаралеливание.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог