Многоядерный парсинг текстового файла

Причины, почему селекторы на основе id не работают

  1. Элемент / DOM с указанным идентификатором еще не существует.
  2. Элемент существует, но он не является зарегистрированный в DOM [в случае, если HTML-узлы динамически добавляются из ответов Ajax].
  3. Присутствует более одного элемента с тем же идентификатором, который вызывает конфликт.

Решения

  1. Попробуйте получить доступ к элементу после его объявления или, альтернативно, использовать такие вещи, как $(document).ready();
  2. . Для элементов, исходящих из ответов Ajax, используйте метод .bind() для jQuery. В старых версиях jQuery для этого было .live().
  3. Используйте инструменты [например, плагин webdeveloper для браузеров], чтобы найти дубликаты идентификаторов и удалить их.
9
задан Ijas Ameenudeen 20 January 2019 в 13:56
поделиться

7 ответов

Я пошел бы с Вашей исходной идеей. Если Вы обеспокоены, что очередь могла бы получить слишком большую реализацию буферная зона для него (т.е. Если, получает выше 100 строк остановку, читая файл и если это добирается ниже 20, затем начинают читать снова. Необходимо было бы сделать некоторое тестирование для нахождения оптимальных барьеров). Сделайте его так, чтобы любой из потоков мог потенциально быть "потоком читателя", поскольку это должно заблокировать очередь для вытаскивания объекта так или иначе, это может также проверить, чтобы видеть, был ли "низкий буферный регион" поражен и начинает читать снова. В то время как это делает это, другие потоки могут считать остальную часть очереди.

Или если Вы предпочитаете, сделали, чтобы один читатель распараллелил, присваивают строки трем другим потокам процессора (через их собственные очереди) и реализуют крадущую работу стратегию. Я никогда не делал этого так, я не знаю, как трудно это.

9
ответ дан 4 December 2019 в 09:15
поделиться

Ответ Mark's является более простым, более изящным решением. Почему создают сложная программа с коммуникацией межпотока, если это не необходимо? Породите 4 потока. Каждый поток вычисляет size-of-file/4, чтобы решить, что это - стартовая точка (и точка остановки). Каждый поток может затем работать полностью независимо.

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

9
ответ дан 4 December 2019 в 09:15
поделиться

Это устранит узкие места наличия единственного потока, делают чтение:

open file
for each thread n=0,1,2,3:
    seek to file offset 1/n*filesize
    scan to next complete line
    process all lines in your part of the file
3
ответ дан 4 December 2019 в 09:15
поделиться

Так как узкое место обычно будет в обработке а не чтении при контакте с файлами, я пошел бы с шаблоном производителя-потребителя. Чтобы постараться не блокировать, я посмотрел бы на блокировку бесплатные списки. Так как Вы используете C#, можно смотреть на Свободный от блокировок код Списка Julian Bucknall.

1
ответ дан 4 December 2019 в 09:15
поделиться

@lomaxx

@Derek и Mark: Мне жаль, что не было способа принять 2 ответа. Я оказываюсь перед необходимостью заканчивать тем, что шел с решением Wolfbyte, потому что, если я разделил файл на разделы n, существует потенциал для потока для случайной встречи с пакетом "медленных" транзакций, однако если я обрабатывал файл, где каждый процесс, как гарантировали, потребует равного объема обработки затем, я действительно люблю решение просто разделения файла в блоки и присвоение каждого блока к потоку и быть сделанным с ним.

Никакие заботы. Если кластеризованные "медленные" транзакции являются проблемой, то решением для организации очередей является способ пойти. В зависимости от того, как быстро или медленный средняя транзакция, Вы могли бы также хотеть посмотреть на присвоение нескольких строк за один раз каждому рабочему. Это сократит синхронизацию наверху. Аналогично, Вы, возможно, должны были бы оптимизировать свой размер буфера. Конечно, оба из них являются оптимизацией, которую необходимо, вероятно, только сделать после профилирования. (Никакой смысл в волнении по поводу синхронизации, если это не узкое место.)

0
ответ дан 4 December 2019 в 09:15
поделиться

Если текст, который Вы анализируете, составлен из повторных строк и маркеров, повредите файл в блоки, и для каждого блока у Вас мог быть один поток, предварительно анализируют его в маркеры, состоящие из ключевых слов, "пунктуации", Строк идентификатора и значений. Строка выдерживает сравнение, и поиски могут быть довольно дорогими и исчезнуть, это к нескольким рабочим потокам может ускорить чисто логическое / семантическая часть кода, если это не должно делать строковых поисков и сравнений.

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

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

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

С другой стороны, большие файлы могут быть с отображенной памятью и "потребовать" загруженный. Если у Вас есть больше потоков, работающих над обработкой файла, чем центральные процессоры (обычно потоки =, 1.5-2X ЦП является большим количеством для приложений подкачки по обращению), потоки, которые останавливаются на IO для файла с отображенной памятью, остановятся автоматически от ОС, пока их память не будет готова, и другие потоки продолжат обрабатывать.

0
ответ дан 4 December 2019 в 09:15
поделиться

Мой опыт с Java, не C#, таким образом, извинения, если эти решения не применяются.

Непосредственное решение, которое я могу продумать первое, что пришло на ум, состояло бы в том, чтобы иметь исполнителя, который выполняет 3 потока (использование Executors.newFixedThreadPool, скажите). Для каждой строки/записи, считанной из входного файла, исчерпайте задание в исполнителе (использование ExecutorService.submit). Исполнитель поставит запросы в очередь на Вас и выделит между 3 потоками.

Вероятно, лучшие решения существуют, но надо надеяться который сделает задание.:-)

ETA: много Походит на второе решение Wolfbyte.:-)

ETA2: System.Threading.ThreadPool походит на очень похожую идею в.NET. Я никогда не использовал его, но это может стоить Вашего в то время как!

1
ответ дан 4 December 2019 в 09:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: