LINUX.ORG.RU

Чем заменить медленный PHP

 , , ,


0

3

Есть скрипт, очень простой. Входные данные - два словаря (просто два файла, где по слову на каждой строке). Несколько текстов - это просто строка.

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

Проблема - сделал словарь размером 400Мб и тут даже текст в одно слово - это очень и очень долго.

На чем переписать под Debian? Думал про bash, но вспомнил про python - и понял, что не знаю что выбрать. Учитывая bash я не знаю, а python немного знаю, а нужно максимум скорости.... но получу ли я ее на bash? Есть мечты отделать парой строк через exec...

Т.е. он каждое слово соотведствующее регулярке из текста ищет в словаре?

Словарь отсортирован? Тут для доступа к словарю нужно что-то похожее на индексы у БД. Чтобы не было нужды перебирать весь словарь.

Fermion ()
Ответ на: комментарий от postscreen

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

что-то я не понял - тебе чего нужно найти сколько раз в тексте встречается слово из словаря ?

Ну разбей исходный текст по словам ( по пробелам ) и ищи совпадения без реэкспом по прямому совпадению ...

Jopich1 ()
Ответ на: комментарий от postscreen

этот кусок вполне переписываем на баш, только вместо 64000 байтов будет строго 1 строка

но если тебе скучно, можешь взять golang||java||C#, читать файл построчно и асинхронно запускать поиск по регулярке, как только строка считалась

если тебе скучно и есть алкоголь||вещества, можешь взять rust||c++

Ford_Focus ★★★★★ ()
Ответ на: комментарий от postscreen

быстрый php выглядит как смена алгоритма с «50 миллионов раз регэкспами колбасим текст любой длины» на что-то более разумное.

а скорее всего - в разумной постановке задачи

anonymous ()

нужно максимум скорости.... но получу ли я ее на bash?

Скорость самых быстрых морских черепах на суше.

Из этих двоих бери змеюку не задумываясь

annulen ★★★★★ ()
Ответ на: комментарий от annulen

мы как-то лулзов ради сравнивали в подобной задаче ruby 1.9.3 против баша. баш отрывался от руби просто в десятки раз на почти 2 гиговом файле :)

не стоит обижать малышей они взрослых (С) позвать могут :)

Ford_Focus ★★★★★ ()
Последнее исправление: Ford_Focus (всего исправлений: 1)
Ответ на: комментарий от postscreen

это не говоря уже о милых мелочах вроде поиска всех вхождений через preg_match_all а потом проверке что там есть хотя бы одно вхождение в count($result[0])

или проверке в цикле 50 миллионов раз !in_array(trim($buffer), $isst_words. пэхапэшники те еще говноеды, но надо же хоть немного понимать, почему это плохо.

в общем, проблема не в медленном пэхапэ, и не в том, что ты не знаешь питон. проблема в том, что ты вообще не одупляешь, что ты делаешь. тут не инструмент надо менять

anonymous ()

а нужно максимум скорости.... но получу ли я ее на bash?

Господь с вами. Язык коммандной оболочки и скорость — это на разных полюсах.

Возьмите хотя бы АВК, что ли. А если задача совсем примитивная, то может и grep’а хватить.

Zmicier ★★★★★ ()
Последнее исправление: Zmicier (всего исправлений: 1)
Ответ на: комментарий от ism

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

while (($buffer = fgets($handle, 64000)) !== false) { 
	preg_match_all('/[^а-я]'.trim($buffer).'[^а-я]/iSu', $text, $result); 
	if( count($result[0]) != 0 and !in_array(trim($buffer), $isst_words) ){ 
		$isst_words[] = trim($buffer); 
	}
}
anonymous ()

Нужно регулярным выражением

вот просто нет. Потому, что пони.

1) читаем словарь в память, кладем в хэшмап/ассоциативный массив, хз как оно в похапе называется, обзываем dict

2) читаем текст, разбиваем его на массив строк чем-нито типа split, обзываем input_words

3) заводим хэшмап найденных в тексте слов, обзываем found_words

4) проходим по массиву input_words, каждое слово проверяем на:

4.1) нахождение в found_words, если есть - пропускаем

4.2) нахождение в dict, если есть - добавляем в found_words

5) ключи found_words - искомое «все, что удалось найти»

arkhnchul ★★ ()
Последнее исправление: arkhnchul (всего исправлений: 2)

Чем заменить медленный PHP
Думал про bash, но вспомнил про python - и понял, что не знаю что выбрать. Учитывая bash я не знаю, а python немного знаю, а нужно максимум скорости

python заметно медленнее, чем PHP, bash — НАМНОГО медленнее :)

Смотреть нужно в сторону Java/Golang/Rust.

Я сам в подобной истории, когда производительности PHP не хватает, стал Go использовать. Брат жив.

KRoN73 ★★★★★ ()

1. если хочешь мгновенный результат, то засунуть словарь в индекс систему - solr, elastic.

2. если устраивает просто ускорение в 10-20 раз, но разбей словарь по индексу - хотя бы на первой букве. получшь n dict файлов, по которому будешь в около n раз быстрее искать.

язык не имеет значения.

vtVitus ★★★★★ ()
Ответ на: комментарий от postscreen

Словарь нужно читать не по одному слову за раз, а хотя бы по 100к слов. Можно и сразу весь, 400Мб это не много.

trim нужно делать один раз.

Вместо preg_match_all достаточно preg_match - тебе же всё равно нужно узнать только факт что слово встречается. Зачем парсить весь текст и выбрасывать результат?

Самый эпик - in_array. Сделай хэш, и проверяй по array_key_exists.

no-such-file ★★★★★ ()
Ответ на: комментарий от KRoN73

У опа проблема не выборе языка, а в алгоритме.

python заметно медленнее, чем PHP

Весьма спорное утверждение. На каких задачах? Каком-то синтетическом тесте? php научился в асинхронность? Хотя бы не умирать после запроса? Для питона есть всякие numpy, cython, pypy если уж очень надо.

pawnhearts ★★★★ ()
Ответ на: комментарий от pawnhearts

Весьма спорное утверждение. На каких задачах?

На задаче топикстартера :)

У опа проблема не выборе языка, а в алгоритме.

Само собой. Но это другая история.

KRoN73 ★★★★★ ()

Словарь надо билдить в конечный автомат при загрузке. Чтобы быстро билдить - надо делать это лениво. Смотри конкурс от компании Hola, там народ фильтры по email писал на JS. Есть очень быстрые решения с кодом + статьи на хабре описывающие код.

Norgat ★★★★★ ()
Ответ на: комментарий от anonymous

Хм.. Кое что я не правильно задании понял, но да ладно. Вот довольно быстрый код на PHP. Можно сделать намного быстрее с отсортированным словарём, но для этого надо постараться, а мне лень. :-P

<?php

$text = "Мама мыла раму";
$words = array_unique(array_map('mb_strtolower', preg_split("~\W+~u", $text)));

//We suppose dictionary is normalized already: contains only lowercased words and no empty strings
$foundWords = [];
$fh = fopen('dictionary.txt', 'r');
while ($strRaw = fgets($fh)) {
    $str = trim($strRaw);
    if (in_array($str, $words)) {
        $foundWords[] = $str;
    }
}
fclose($fh);

print_r($foundWords);

anonymous ()