2010-11-06 3 views
4

Я собираюсь запустить проект, который будет принимать блоки текста, анализируя много данных в них на какой-то объект, который затем может быть сериализован, сохранен и статистически/данные, полученные из. Это должно быть как можно быстрее, так как у меня есть> 10 000 000 блоков текста, которые мне нужно начинать, и получат 100 000 тысяч в день.Самый быстрый способ разбора больших строк (многопоточность)

Я запускаю это на системе с 12 ядрами xeon + hyper threading. У меня также есть доступ/немного знать о программировании CUDA, но для струнных вещей думаю, что это не подходит. Из каждой строки мне нужно разбирать много данных, а некоторые из них я знаю, какие позиции я, а некоторые нет, и нужно использовать regex/something smart.

Так считают что-то вроде этого:

object[] parseAll (string [] stringsToParse) 
{ 
    parallel foreach 
      parse(string[n]) 
} 

object parse(string s) 
{ 
    try to use exact positions/substring etc here instead of regex's 
} 

Так мои вопросы:

  • Сколько медленнее использует регулярное выражение, чтобы подстрока.
  • Является ли .NET значительно медленнее, чем другие языки.
  • Какую оптимизацию (если таковая имеется) можно сделать для максимизации параллелизма.
  • Что-нибудь еще, что я не рассматривал?

Спасибо за любую помощь! Извините, если это долгое время.

+1

Мое предположение - IO будет ограничивающим фактором. Настройте несколько простых тестовых примеров и проанализируйте использование ресурсов и т. Д. – 2010-11-06 19:07:24

+0

На современном ПК объем, о котором вы говорили, является небольшим обжариванием для работы с данными. Метод, который вы предлагаете, звучит, э-э, звук. Подумайте также об использовании таких вещей, как IndexOf, когда вы знаете, что можете безопасно искать фиксированную строку. Избегайте ToUpper/Lower, если можете, если функции сравнения поддерживают игнорирование случая. Но сначала, напишите для удобочитаемости, а затем оптимизируйте. – Will

ответ

4

Насколько медленнее используется регулярное выражение для substr.
Если вы ищете точную строку, substr будет быстрее. Однако регулярные выражения сильно оптимизированы. Они (или, по крайней мере, части) скомпилированы в IL, и вы можете даже сохранить эти скомпилированные версии в отдельной сборке, используя Regex.CompileToAssembly. См. http://msdn.microsoft.com/en-us/library/9ek5zak6.aspx для получения дополнительной информации.

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

Какую оптимизацию (если таковая имеется) можно сделать для максимизации параллелизма.
С помощью Task.Factory.StartNew вы можете планировать задачи для запуска в пуле потоков. Вы также можете взглянуть на TPL (Task Parallel Library, из которых Task - часть). У этого есть много конструкций, которые помогут вам распараллеливать работу и позволяют строить такие конструкции, как Parallel.ForEach(), для выполнения итерации по нескольким потокам. См. http://msdn.microsoft.com/en-us/library/dd460717.aspx для получения дополнительной информации.

Что-нибудь еще, что я не рассматривал?
Одна из вещей, которая повредит вам этим объемом данных, - управление памятью. Несколько вещей, чтобы принять во внимание: выделение памяти

  • Limit: попытаться повторно использовать одни и те же буфера для одного документа, вместо того, чтобы копировать их, когда вам нужна только часть. Скажем, вам нужно работать с диапазоном, начинающимся с char 1000 до 2000, не копировать этот диапазон в новый буфер, а строить свой код для работы только в этом диапазоне.Это сделает ваш код сложным, но он сохранит вам выделение памяти;

  • StringBuilder - важный класс. Если вы еще не знаете об этом, посмотрите.

+1

Полностью согласовано. В частности, остерегайтесь части выделения памяти. При таком большом объеме может быть возможно пострадать от фрагментации памяти. Я предлагаю вам прочитать и понять это, если вы еще этого не сделали: http: // www.simple-talk.com/dotnet/.net-framework/the-dangers-of-the-large-object-heap/ –

0

Google недавно объявил, что это внутренний язык обработки текста (который, как представляется, как подмножество Python/Perl сделал для параллельной обработки в значительной степени).

http://code.google.com/p/szl/ - Sawzall.

+1

это выглядит довольно круто/интересно проверит. –

1

Я не знаю, какую обработку вы здесь делаете, но если вы говорите сотни тысяч строк в день, это кажется довольно маленьким числом. Предположим, что вы получаете 1 миллион новых строк для обработки каждый день, и вы можете полностью выполнить 10 из этих 12 ядер Xeon. Это 100 000 строк на ядро ​​в день. Есть 86 400 секунд в день, поэтому мы говорим 0,864 секунды за строку. Это лот разбора.

Я повторю рекомендации, сделанные @Pieter, особенно там, где он предлагает сделать измерения, чтобы узнать, сколько времени потребуется для обработки. Лучше всего получить что-то вверх и работать, затем выяснить, как сделать это быстрее, если вам нужно. Я думаю, вы будете удивлены тому, как часто вам не нужно оптимизировать. (Я знаю, что это ересь для мастеров оптимизации, но время процессора дешево и время программиста дорого.)

Насколько медленнее используется регулярное выражение для substr?

Это зависит полностью от того, насколько сложны ваши регулярные выражения. Как сказал @Pieter, если вы ищете одну строку, String.Contains, вероятно, будет быстрее. Вы также можете использовать String.IndexOfAny, если вы ищете постоянные строки. Регулярные выражения не нужны, если вы не ищете шаблоны, которые не могут быть представлены как постоянные строки.

Является ли .NET значительно медленнее, чем другие языки?

В приложениях с интенсивным процессором .NET может быть медленнее, чем собственные приложения. Иногда. Если это так, он обычно находится в диапазоне от 5 до 20 процентов и чаще всего от 7 до 12 процентов. Это всего лишь код, выполняющийся изолированно. Вы должны учитывать другие факторы, например, как долго вы занимаетесь разработкой программы на этом другом языке и насколько сложно делиться данными между родным приложением и остальной частью вашей системы.

+0

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

+0

@Merlyn: Да, я игнорировал пики. Я также переоценил ежедневную нагрузку. Кроме того, не было упоминания о необходимости «реального времени». Я интерпретировал вопрос как «как я могу идти в ногу с грузом?» и мой ответ отражает это. Да, во время пиковых периодов в очереди могут быть элементы, оставшиеся в очереди. Но это почти всегда так, если вы не проектируете систему для пика, а это означает, что в нерабочее время вы используете простоя оборудования. –

+0

Правда. Все зависит от того, каковы его настоящие требования. «Быстро, насколько это возможно» показывает, что он хочет хорошего времени отклика или, по крайней мере, хорошего времени на поворот, но он также показывает, что он не знает, что ему нужно, чтобы гарантировать, чтобы гарантировать какой-либо определенный уровень обслуживания. Я думаю, что предоставление математики и данных, которые он имеет сейчас, может дать ему ложное чувство безопасности, что он должным образом рассмотрел его требования и будет встречаться с ними. Кстати, я также думаю о сетевом сервисе. Его приложение может не отражать это, и в этом случае простые перформационные показатели могут быть точными. –

0

Если вы хотите выполнить быстрый синтаксический анализ строк на C#, вы можете рассмотреть возможность взглянуть на новый проект NLib. Он содержит строковые расширения для быстрого поиска строк. Например, IndexOfAny (строка []) и IndexOfNotAny. Они также содержат перегрузки с аргументом StringComparison.

Смежные вопросы