![]() |
|
Модераторы: Partizan, gambit |
![]()
|
|
| Suppir |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Добрый день!
У меня в директории 1.5 Гб txt-файлов. Необходимо в каждом файле проверить строки регулярным выражением, и в случае совпадения записать строки в результирующий файл. Вот код на Perl
Время работы perl (perl 5.12 Activestate) - 41 секунда, потребление памяти 25 Мб. Аналогичный код на c#
Время работы программы (.NET Fraimwork 3.5) - 77 секунд, потребление памяти 5 Мб. Действительно ли c# медленней Perl в аналогичных задачах, или проблема (как я подозреваю) в неправильном коде? Как можно ускорить код c# (используя именно регулярные выражения). Целиком файлы нельзя забирать в переменные, т.к. файлы по 100 - 300 Мб размером. Это сообщение отредактировал(а) Suppir - 4.9.2010, 13:00 |
||||
|
|||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 6 Всего: 118 |
Suppir, надо скомпилировать регэксп. Грубо говоря у вас сейчас каждый match регэксп парсится заново.
ну а вообще конкретно в этой задаче от регэкспа нету пользы ). и да, памяти c# будет кушать больше... да и быстрее врядли будет работать, нежели парловый pcre. -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| Suppir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
jonie, для это задачи понятно. У меня В программе несколько десятков рег. выражений - нужно переписать на c# все. Вот и и думаю, почему медленней получается? Ведь это уже скомпилированная программа, а Perl - всего лишь интерпретатор.
Насчет компиляции регулярных выражений. В Perl, если регекс не содержит интерполируемых переменных, то он автоматически компилируется. Насчет потребления памяти - сама программа на c# меньше памяти потребляет (5 Мб вместо 25 перла). Однако важнее скорость работы. |
|||
|
||||
| Kaerus |
|
|||
|
WPF'er ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 3.9.2010 Репутация: нет Всего: 1 |
Может не стоит считывать файл построчно. А сразу считать целиком с помощью StreamReader.ReadToEnd или хотя-бы блоками
Это сообщение отредактировал(а) Kaerus - 4.9.2010, 23:41 |
|||
|
||||
| Suppir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Kaerus, файлы очень большие для того, чтобы их целиком помечать в память + нужно перекодировать из CP866 + у меня все алгоритмы рассчитаны на построчное чтение.
Можно считать блоками, разбить блок на массив строк и двигаться по массиву, но это будет (имхо) медленней работать и менее удобно |
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 6 Всего: 118 |
Suppir, в .net по умолчанию не компилируются регэкспы.
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| Kaerus |
|
|||
|
WPF'er ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 3.9.2010 Репутация: нет Всего: 1 |
Потестил я твой код на 5 файла по 500 МБ (в сумме 15 мил. строк), вот что показывает профилирование
![]() Судя по нему основная нагрузка связана с чтением строк. Немного помогает увеличение буфера файлов до 1 МБ. |
|||
|
||||
| Suppir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Kaerus, т.е. основное время тратится на чтение строки?
|
|||
|
||||
| Kaerus |
|
|||
|
WPF'er ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 3.9.2010 Репутация: нет Всего: 1 |
Да, но IsMatch тоже с счётов сбрасывать не стоит. Пока там одно рег. выражение не страшно, а если их будет 50 - они уже будут сильнее влиять.
Переделал твой код под чтение напрямую из FileStream блоками в буфер, с последующим переводом в строку через Encoding.GetString(...) - выигрыш скорости не более 5% (StreamReader - 40.7 сек, FileStream - 39.8 сек). Кстати разбивание на отдельные потоки (у меня 3 процессора), тоже не дает плюса в производительности. Вывод: StreamReader хорошо кеширует чтение, так что переделывать не стоит. Вообще в таких задачах как чтение больших данных с диска, C# не может дать преимущество перед скриптовыми языками |
|||
|
||||
| Suppir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Понятно, спасибо.
|
|||
|
||||
| Suppir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Kaerus,
"C# не может дать преимущество перед скриптовыми языками" Я делал тесты с Ruby, Python, AutoIt и Perl в подобных задачах Perl работает намного быстрее всех, Python помедленней (примерно как c#), Ruby 1.9 и AutoIt медленней Perl на порядок, т.е. в 10 раз. Причем AutoIt был еще медленней (раз в 15), я связался с разработчиками и они в апреле немножко пофиксили функцию чтения строк из файла (раньше чтение было вообще не буферизовано!). Это сообщение отредактировал(а) Suppir - 6.9.2010, 09:33 |
|||
|
||||
| DenWPF |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1659 Регистрация: 26.9.2009 Репутация: нет Всего: 1 |
Ну так есть запас памяти можно к примеру написать потоки, память увеличиться, а время сократиться.
получиться примерно 5метров*5 - память и делим на 5 время, и будет быстрее ... IMHO |
|||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | .NET для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |