Вопрос: Substring, left, right, mid и скорость в цикле | Добавлено: 26.05.10 00:09 |
Автор вопроса: ![]() |
Здравствуйте, подскажите пожалуйста.
Есть куча файлов по 1-10 мегобайт, в которых перечислена продукция. Генерируются старой сетевой программой, которую заменить и переписать возможности нет. Перечислена продукция смешным образом - продукт1@цена1$количество1& продукт2@цена2$количество2& ... Возникла потребность обработать информацию. Считываю следующим образом: fs = New FileStream("имя файла", FileMode.Open) sr = New StreamReader(fsr, Encoding.Default) Do Until sr.EndOfStream ... = sr.ReadLine .......... Далее в цикле приходится использовать InStr (для считывания позиций @, $, & в строке) Microsoft.VisualBasic.Left Microsoft.VisualBasic.right Microsoft.VisualBasic.mid Скорость удручает. Замена mid и left на substring ничего не ускорило, а вместо right тогда ещё и len приходится использовать. Читал в http://www.vbnet.ru/forum/show.aspx?id=58483 и на забугорных форумах, что .net есть чего-то "родное", что более эффективно, но так и не было сказано что именно. Буду признателен за подсказку :) |
Ответы | Всего ответов: 31 |
Номер ответа: 1 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 24 Ответов: 363 |
Профиль | Цитата | #1 | Добавлено: 26.05.10 01:28 |
Я бы загрузил сначала весь файл в StringBuilder он примерно на порядок быстрее String, а потом от этого бы начал плясать. |
Номер ответа: 2 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #2 | Добавлено: 26.05.10 11:14 |
Я бы загрузил сначала весь файл в StringBuilder он примерно на порядок быстрее String, а потом от этого бы начал плясать.
Это не тот случай когда нужно юзать StringBuilder, тут он не даст прироста скорости.. Reader,имхо, для считывания наиболее быстрый вариант.. InStr (для считывания позиций @, $, & в строке)
Для этого есть IndexOf & LastIndexOf mid , left, right
Это фсе в топку.. используй Substring и Lenght Кроме всего прочего из "Родных средств" могу рекомендовать ф-ю Split которая на вход принимает массив разделителей (в твом случае это @, $, & ![]() И второй вариант - это использовать регулярные выражения.. За быстродействия обоих вариантов ничего сказать не могу - это надо делать бенчмарки... |
Номер ответа: 3 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Лидер форума ICQ: 216865379 Вопросов: 106 Ответов: 9979 |
Web-сайт: Профиль | Цитата | #3 | Добавлено: 26.05.10 14:16 |
Может, просто пробегать символы и сохранять индекс начала нужной подстроки? Ни одного копирования, пробег по файлу 1 раз. |
Номер ответа: 4 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #4 | Добавлено: 26.05.10 15:03 |
Ни одного копирования
а смысл? ему копировать по любому надо будет.. Наверняка, все эти пляски с бубном для того чтоб привести эти файлы как какому то другому виду.. или перенос данных в БД.. |
Номер ответа: 5 Автор ответа: ![]() ![]() ![]() Вопросов: 1 Ответов: 2 |
Профиль | Цитата | #5 | Добавлено: 26.05.10 15:07 |
Substring и Lenght по скорости получились почти такими же, как left, right, mid. И IndexOf & LastIndexOf вместо InStr тоже скорости не прибавил.
Кроме всего прочего из "Родных средств" могу рекомендовать ф-ю Split
Сделал replace всех @, $, & на *(в принципе, так менять могу в самой программе постоянно), т.е получилось: продукт1*цена1*количество1* продукт2*цена2*количество2* ... В цикле:
Т.е. а(0) = продукт1, а(1) = цена1, а(2) = количество1 и т.д. Заняло в 1,2 раза больше времени. Ни одного копирования, пробег по файлу 1 раз.
Извините, не понял. Substring с IndexOf & LastIndexOf это вроде не отменяет? Мне каждое значение между * sr.ReadLine надо проверять в if...then. Получается Substring и Lenght буду использовать... |
Номер ответа: 6 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #6 | Добавлено: 26.05.10 16:34 |
Заняло в 1,2 раза больше времени.
Я сделал тест на 500000 строках.. Размер файла получился ~31 метр (у тебя максимально 10 метров). Тестировал 2 метода: - Method1: Substring + IndexOf - Method2: Split Результаты получил следующие.. =========Begin test========= Method1: 00:00:00.3906250 Method2: 00:00:00.5625000 =========Begin test========= Method1: 00:00:00.3906250 Method2: 00:00:00.5468750 =========Begin test========= Method1: 00:00:00.3750000 Method2: 00:00:00.5625000 имхо,обработать полмиллиона строк за 0,4-0,6 сек вполне нормальный результат.. из результатов очевидно, что первый метод гораздо быстрее второго.. регулярные выражения даже тестировать не стал.. |
Номер ответа: 7 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Лидер форума ICQ: 216865379 Вопросов: 106 Ответов: 9979 |
Web-сайт: Профиль | Цитата | #7 | Добавлено: 26.05.10 19:00 |
вроде не отменяет?
Отменяет. 0,4-0,6 сек
Фига у тебя винтяра. |
Номер ответа: 8 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Разработчик Вопросов: 130 Ответов: 6602 |
Профиль | Цитата | #8 | Добавлено: 26.05.10 20:10 |
Через SR.ReadLine считывается строка
Потом разбирается чем угодно (IndexOf, регулярными выражениями). Я не могу понять как нжуно написать код, чтоб манипуляции со сторокой длиной в несколько десятков символов занимали хоть сколько-то времени |
Номер ответа: 9 Автор ответа: ![]() ![]() ![]() Вопросов: 1 Ответов: 2 |
Профиль | Цитата | #9 | Добавлено: 27.05.10 00:11 |
Время они занимают постольку, поскольку файлов этих на несколько гигабайт, а в циклах прокручиваются они с разбиением строки sr.readline много раз. Просто экономическая статистика обрабатывается в научных целях. Использовал Microsoft.VisualBasic.right/left/mid, который все ругают, думал, что заменив его все ускорится. Однако, заменив на substring быстрей не стало. Со split'ом стало медленней. Вот и все.
Всем спасибо за помощь! |
Номер ответа: 10 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Разработчик Вопросов: 130 Ответов: 6602 |
Профиль | Цитата | #10 | Добавлено: 27.05.10 19:07 |
Считывание данных с диска выполняется несравнимо дольше чем их анализ, и здесь от способа разбиения суммарная скорость не зависит. Разумеется, если ты нигде не накосячил |
Номер ответа: 11 Автор ответа: ![]() ![]() ![]() ![]() ![]() ICQ: adamis@list.ru Вопросов: 153 Ответов: 3632 |
Профиль | Цитата | #11 | Добавлено: 29.05.10 00:38 |
Короче просто
ТС юзал дотнэт без религиозного трепета и великий бох фрэймворк наказал его за это ![]() |
Номер ответа: 12 Автор ответа: ![]() ![]() ![]() ![]() Вопросов: 246 Ответов: 3333 |
Web-сайт: Профиль | Цитата | #12 | Добавлено: 30.05.10 15:29 |
Artyom пишет:
и здесь от способа разбиения суммарная скорость не зависит. Ну почему... Можно например, чуть-чуть сэкономить время: считываем первые 10'000 строк, запускаем обработку отдельным потоком, тем временем считываем другие десять тысяч строк, запускаем обработку еще одним потоком и т.п. В данном случае время обработки сведется к минимому, так как время будет тратиться только на считывание ботвы с жесткого диска (ибо оброаботки, запущенные параллельно, будут завершаться гораздо быстрее), и обработка не будет задерживать считывание. |
Номер ответа: 13 Автор ответа: ![]() ![]() ![]() ![]() ![]() ICQ: adamis@list.ru Вопросов: 153 Ответов: 3632 |
Профиль | Цитата | #13 | Добавлено: 30.05.10 16:35 |
обработка совсем не будет задерживать чтение если вгрузить всё за один раз |
Номер ответа: 14 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #14 | Добавлено: 30.05.10 18:48 |
и обработка не будет задерживать считывание.
Как раз таки ситуация с точностью до наоборот... там считывание задерживает обработку. Файловые операции ввода-вывода несравнимо тормознутее операций обработки строк, и ускорить ты это не сомжешь.. все ограничено скоростью винта. обработка совсем не будет задерживать чтение если вгрузить всё за один раз
она и так ничего не задерживает... а вот грузить в память большие объемы данных - это есть криво. |
Номер ответа: 15 Автор ответа: ![]() ![]() ![]() ![]() ![]() ICQ: adamis@list.ru Вопросов: 153 Ответов: 3632 |
Профиль | Цитата | #15 | Добавлено: 30.05.10 20:33 |
нэтбук сцуко клава моросит
Михаил пишет:
Есть куча файлов по 1-10 мегобайт Ну даже если и как у тебя EROS пишет:
Размер файла получился ~31 метр большим объемом это не назовешь сами говорите, что мелочится с ресурсами на современных машинах неприлично |
|