Как эффективно подсчитывать кортежи символов в PHP ⇐ Php
Как эффективно подсчитывать кортежи символов в PHP
Мне нужно быстро посчитать кортежи символов (или N-граммы) в огромных файлах/строках (от 10 МБ до 1 ГБ +) в проекте PHP (классификаторе файлов).
Текущая реализация рассчитана на количество одиночных символов (N=1) и выполняется очень быстро за 0,x сек. для очень больших строк (до 1 миллиарда символов/байт)
// возвращает ассоциативный массив [char => count] функциональные частоты($txt) { $index = count_chars($txt, 1); foreach ($index как $code => $nb) { $count[chr($code)] = $nb; } вернуть $счет; } Я хотел бы изменить его для работы с биграммами (N=2 или более), поэтому я написал это
// возвращает ассоциативный массив [charTuple => count] функция частоты($txt, $n) { $length = strlen($txt) - $n+1; for ($i = 0; $i < $length; $i++) { @$count [substr($txt, $i, $n)] ++; } вернуть $счет; } // Обратите внимание: '@' некрасиво, но кажется быстрее, чем если бы isset() Однако этот код очень медленный: 45 секунд. в том же файле для N = 1 (примерно в 100 раз медленнее) и более минуты для N = 2.
Я попробовал альтернативу прямого доступа + конкатенации:
function twograms($txt) { $length = strlen($txt) - $n; for ($i = 0; $i < $length; $i++) { @$count [$txt[$i] . $txt[$i+1] ] ++; } вернуть $счет; } И он работает немного быстрее — 42 секунды. (+/- погрешность)
Это по-прежнему слишком медленно и не соответствует эффективности встроенной функции count_char().
Есть ли альтернатива? Есть ли способ более эффективно подсчитывать кортежи символов?
РЕДАКТИРОВАТЬ: я обновил онлайн-ссылку PHP для тестирования/тестирования, чтобы принять во внимание предложение с помощью str_split и array_count_values и соответствующей памяти. использование.
Мне нужно быстро посчитать кортежи символов (или N-граммы) в огромных файлах/строках (от 10 МБ до 1 ГБ +) в проекте PHP (классификаторе файлов).
Текущая реализация рассчитана на количество одиночных символов (N=1) и выполняется очень быстро за 0,x сек. для очень больших строк (до 1 миллиарда символов/байт)
// возвращает ассоциативный массив [char => count] функциональные частоты($txt) { $index = count_chars($txt, 1); foreach ($index как $code => $nb) { $count[chr($code)] = $nb; } вернуть $счет; } Я хотел бы изменить его для работы с биграммами (N=2 или более), поэтому я написал это
// возвращает ассоциативный массив [charTuple => count] функция частоты($txt, $n) { $length = strlen($txt) - $n+1; for ($i = 0; $i < $length; $i++) { @$count [substr($txt, $i, $n)] ++; } вернуть $счет; } // Обратите внимание: '@' некрасиво, но кажется быстрее, чем если бы isset() Однако этот код очень медленный: 45 секунд. в том же файле для N = 1 (примерно в 100 раз медленнее) и более минуты для N = 2.
Я попробовал альтернативу прямого доступа + конкатенации:
function twograms($txt) { $length = strlen($txt) - $n; for ($i = 0; $i < $length; $i++) { @$count [$txt[$i] . $txt[$i+1] ] ++; } вернуть $счет; } И он работает немного быстрее — 42 секунды. (+/- погрешность)
Это по-прежнему слишком медленно и не соответствует эффективности встроенной функции count_char().
Есть ли альтернатива? Есть ли способ более эффективно подсчитывать кортежи символов?
РЕДАКТИРОВАТЬ: я обновил онлайн-ссылку PHP для тестирования/тестирования, чтобы принять во внимание предложение с помощью str_split и array_count_values и соответствующей памяти. использование.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение