powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Быстрый перебор из файла
12 сообщений из 12, страница 1 из 1
Быстрый перебор из файла
    #39003176
alexzf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Есть некий файл (текстовый). Есть возможность открывать его как в BINARY так и в ASCII. В этом файле более 1млн таких вот строк:
автор59208327 G G
59207960 T T
59208595 T T


Ну так вот, после открытия этого файла я пытаюсь сформировать массив вида
автор[59208327] => 'G/G'
...
[59208595] => 'T/T'
....


Вот код которым я это все делаю:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
        $file_handle = fopen($this->_tmpFilePath.$file, "r");
        while (!feof($file_handle)) {
            $line = fgets($file_handle);
            $arr  = preg_split('/\s+/', $line);
            if( isset($arr[1]) ) {
                $matches[trim($arr[0])] = $arr[1]."/".$arr[2];
            }
        }
        fclose($file_handle);



И это занимает очень долгое время (3-4 секунды). Было бы здорово если бы кто нить посоветовал что нить.
...
Рейтинг: 0 / 0
Быстрый перебор из файла
    #39003199
kunaksergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alexzf,
1. Можно считать файл сразу с помощью file_get_contents, и далее работать со строкой в памяти.
2. если у тебя четко такой формат: "59208327 G G", то лучше использовать explode.
3. Не совсем понятно зачем тебе trim($arr[0]), если у тебя разделитель в preg_split('/\s+/'), по идее пробелов там уже не должно быть.
...
Рейтинг: 0 / 0
Быстрый перебор из файла
    #39003380
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
быстрее будет если скажешь зачем тебе это... а вообще обработка файла в лоб, это всегда медленно...можно и на заниматься ерундой, считывая весь файл в память(хотя это быстрее чем твой вариант)..
а
читать его как минимум в размере кратном кластеру и никак не иначе. и не клеить и не разбивать большие строки в памяти... тоессть из куска в 8кбайт скажем не вздумать каждую строку отрезать в цикле.


но мне кажеться тут надо смотреть откуда берёться файл и что с ним дальше делают...

ЗЫ
быстрее всего будет если втроенная(ые) пхпшная функция выполнит всю работу
например хранить в серилизованном виде кусками ..по 1мегабайту скажем (дорисовывая пробелы чтобы кусок был ровно метр, и в цикле считывать мегабайт, де-серилизовать и с предыдущим результатом смержить арей мерге.

слышал в пхп есть и болле ефективные методы хранения масива в файле
...
Рейтинг: 0 / 0
Быстрый перебор из файла
    #39003482
alexzf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alex564657498765453,

Привет,
Файл генерится сторонним приложением, используется и преобразуется в массив для быстрого поиска в нем (поиск по хешу). В дальнейшем не используется. То есть получается... с одной стороны около 100млн строк в БД... с другой стороны файл в 1млн строк. И нужно все данные из файла (найденные в 100млн) записать в бд. Весь процесса достаточно быстро происходит, но хотелось бы выйграть эти 3-4 секунды на обработку этого файла.
file_get_content и дальнейшая обработка его в массив обваливается с Allowed memory size. Пожтому приходится построчно. Как то так.
...
Рейтинг: 0 / 0
Быстрый перебор из файла
    #39003563
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если не упираться в PHP (пара мыслей)...

alexzfФайл генерится сторонним приложением, используется и преобразуется в массив для быстрого поиска в нем (поиск по хешу)Для однократного поиска вполне можно использовать grep. Для многократного, конечно, это уже не годится.

alexzfнужно все данные из файла (найденные в 100млн) записать в бдКак вариант, пропустить файл через awk с целью создать из данных запрос на вставку, а далее его через конвейер отправить клиенту СУБД.
...
Рейтинг: 0 / 0
Быстрый перебор из файла
    #39003738
kunaksergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
чтение блоками, как предлагал товарищ выше:

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
<?php
function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

$time_start = microtime_float();

 $filename="text.txt";
 $filesize=filesize($filename);
 $size=0;
 $block=1024;
 $a=[];
 while($size<$filesize){

 	$content=file_get_contents($filename, NULL, NULL, $size, $block);
 	$a[]=$content;
 	if (($size+$block)<$filesize){
 		$size+=$block;
 	}else{
 		$size+=$filesize-$size;
 	}
}


$time_end = microtime_float();
$time = $time_end - $time_start;

echo $time;

?>



0.13 сек против 3,38 сек.
остальное надо допилить
...
Рейтинг: 0 / 0
Быстрый перебор из файла
    #39004401
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkleЕсли не упираться в PHP (пара мыслей)...

alexzfФайл генерится сторонним приложением, используется и преобразуется в массив для быстрого поиска в нем (поиск по хешу)Для однократного поиска вполне можно использовать grep. Для многократного, конечно, это уже не годится.

alexzfнужно все данные из файла (найденные в 100млн) записать в бдКак вариант, пропустить файл через awk с целью создать из данных запрос на вставку, а далее его через конвейер отправить клиенту СУБД.

не хочу огорчить, но есть три незыблемые истины

1)земля круглая
2)паралельные прямы не пересекаються
3)если говорим на скриптовом языке(php) слово быстро! то слово awk забываем, и даже не вспоминаем. Только sed!!!

ЗЫ
для прикола когда админил файл на пару гигов - почтовый файл, решил вырезать все вложения... написал у в консультации с админами(почему то все админы любят материться кроя все словом авк.) для авка был написан эффективный алгоритм такой задачи(ну просто я предполагал, мало ли..может я не познал дао авка)

для седа написал я - не могу сказать что супер еффективный, написал рабочий.

у седа задача была как и у авка...но только на вывод давал сед вырезаемые вложения, а авка всё остальное(для понта, теоретически будучи увереным что сед намного быстрее, заведомо дал ему более сложную задачу в работе с самым медленым елементом ПС - винчестером(не сата))

результат - то, что сед сделал за 39 секунд вроде, авку понадобилось почти три минуты.
...
Рейтинг: 0 / 0
Быстрый перебор из файла
    #39004416
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kunaksergeyчтение блоками, как предлагал товарищ выше:

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
<?php
function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

$time_start = microtime_float();

 $filename="text.txt";
 $filesize=filesize($filename);
 $size=0;
 $block=1024;
 $a=[];
 while($size<$filesize){

 	$content=file_get_contents($filename, NULL, NULL, $size, $block);
 	$a[]=$content;
 	if (($size+$block)<$filesize){
 		$size+=$block;
 	}else{
 		$size+=$filesize-$size;
 	}
}


$time_end = microtime_float();
$time = $time_end - $time_start;

echo $time;

?>



0.13 сек против 3,38 сек.
остальное надо допилить

спасибо за поддержку.

хочеться спросить-заметить.
Я не уверен в правильности file_get_contents! я могу ошибаться, но помоему - мы вместо открытия файла, чтение блоками, постоянно помня адрес где последний байт читали, знаем где читать следующий (fopen, fread, fclose)

получаем открыть файл, сместиться в нужную позицию считать закрыть.

в идеале...работу можно вести очень эффективно, буферизируя операции с файлами(я про модуль пхп и про операционную систему) но врядли там идеал.

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

---
краткий екскурс как работают масивы, строки, и подобные типы данных.

надо масив,
выделяем 64кбайта(например но обычно помоему с 4кбайт стартует)
и там размещаеться начальное значение масива(если стартово у масива данных больше чем на 4к - сразу будет выделенно больше)

потом когда при очередной дозаписи в масив мы выходим за пределы 4кбайта, создаёться новая переменная размером 2х --- 8к, в неё копируеться 4к старые, и происходит дозапись...

потом 16,32,64...

догадываетесь что мы делаем??? нехило так гоняем байты по оперативке...

данные еффект можно легко пронаблюдать, взяв например читая этот текст включить дваваскриптовую консоль, и создать в ней строку на один гигабайт длиной заполненой случайными символами, но так чтобы символов "а" было не больше 1000

и потом получить результат работы замены регуляркой. в одном случае меняем все символы "а" на "" , в другом случае все мисволы не "а" меняем на ""
- тоесть получим все быквы а из гигабайтной строки, и всю гигабайтную строку с вырезаными буквами а...
мы понимаем - что алгоритмически, и для движка регулярок это одна и таже задача...
беги себе по строке и сравнивай каждый символ с "а"

разница лишь заключаеться в результате! в одном случае мы сформируем посимвольным дописыванием в конец строку из максимум 1000 символов - ни одного копирования изза наращивания размера выделенного под переменную

и вторую строку, где очень часто было перевыделение большего обьяма памяти под строку.
...
Рейтинг: 0 / 0
Быстрый перебор из файла
    #39004451
kunaksergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alex564657498765453,
а где же решение?
...
Рейтинг: 0 / 0
Быстрый перебор из файла
    #39004546
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kunaksergeyalex564657498765453,
а где же решение?
в данном случае незачем читаем по блочкам и пихать в масив...

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

ЗЫ
вообще меня лично очень смущает сама задача... маразмом попахивает.

может даже ваще лучше сразу ввывод в файл сделать ввиде пхп кода описание масива!

всеж смогут из выборки в базе строк, сделать так чтобы каждая строка была правильной строкой пхп кода по типу

'<calc_some_hash>' => array('a'=>1,'b'=>2...,'n'=>1232),

а селект обернуть двумя юнионами, первый возвращает строку
<?php return array(

второй в конце строку
); ?>

или с помощью переменных - если пхп будет офигевать от таких обьемов ...

что в выходном пхп скрипте обьявляеться масив а на 50000 елементов скажем, мержиться с масивом результат, потом переобьявляються 50000 элементов масива а - дабы не пересоздавалась переменная масива, мержаться с результатом, и так заганяеться в результат все миллионы строк...
...
Рейтинг: 0 / 0
Быстрый перебор из файла
    #39004565
kunaksergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alex564657498765453,
держать в памяти массив в 1 лям элементов [key]=>"xxxxxxxxx" мне понадобилось 170М.
...
Рейтинг: 0 / 0
Быстрый перебор из файла
    #39006019
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kunaksergeyalex564657498765453,
держать в памяти массив в 1 лям элементов [key]=>"xxxxxxxxx" мне понадобилось 170М.

я лишь написал советы про работу с большими обьёмами эффективно...как ты верно заметил это сотни мегабайт данных, это не фреймворковая соцсеть где скрипту надо на 10-15 метров отсилы. да и запросов куча но каждый делает маленькую выборку.

насчёт его задачи, я ваще не понимаю почему из базы на 100млн строк мы делаем 1млн и потом этот 1млн надо в базу обратно записывать.

если на то уже пошло, почему в первой базе нельзя делать выборку не данных а сразу строк на вставку в другую базу.... чтоб файлик сразу мусклу давать и пускай вставляет...


да и команду лоуд фром файл никто не отменял...и там можно описать как обработать этот файл
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Быстрый перебор из файла
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]