Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 | 2 | 3 |

 

  Вопрос: 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
Автор ответа:
 s12



Вопросов: 24
Ответов: 363
 Профиль | | #1 Добавлено: 26.05.10 01:28
Я бы загрузил сначала весь файл в StringBuilder он примерно на порядок быстрее String, а потом от этого бы начал плясать.

Ответить

Номер ответа: 2
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #2 Добавлено: 26.05.10 11:14
Я бы загрузил сначала весь файл в StringBuilder он примерно на порядок быстрее String, а потом от этого бы начал плясать.

Это не тот случай когда нужно юзать StringBuilder, тут он не даст прироста скорости.. Reader,имхо, для считывания наиболее быстрый вариант..
InStr (для считывания позиций @, $, & в строке)

Для этого есть IndexOf & LastIndexOf
mid , left, right

Это фсе в топку.. используй Substring и Lenght
Кроме всего прочего из "Родных средств" могу рекомендовать ф-ю Split которая на вход принимает массив разделителей (в твом случае это @, $, &;), а на выходе получишь строковый массив из 3 элементов В этом случае отпадет необходимость использования всех вышеперечисленных ф-й, что, само по себе, достаточно серьезно упростит код.
И второй вариант - это использовать регулярные выражения..
За быстродействия обоих вариантов ничего сказать не могу - это надо делать бенчмарки...

Ответить

Номер ответа: 3
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #3
Добавлено: 26.05.10 14:16
Может, просто пробегать символы и сохранять индекс начала нужной подстроки? Ни одного копирования, пробег по файлу 1 раз.

Ответить

Номер ответа: 4
Автор ответа:
 EROS



Вопросов: 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*
...
В цикле:
  1. s = sr.ReadLine
  2. Dim a() As String = Split(s, "*")

Т.е. а(0) = продукт1, а(1) = цена1, а(2) = количество1 и т.д.
Заняло в 1,2 раза больше времени.
Ни одного копирования, пробег по файлу 1 раз.

Извините, не понял. Substring с IndexOf & LastIndexOf это вроде не отменяет? Мне каждое значение между * sr.ReadLine надо проверять в if...then.

Получается Substring и Lenght буду использовать...

Ответить

Номер ответа: 6
Автор ответа:
 EROS



Вопросов: 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
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #7
Добавлено: 26.05.10 19:00
вроде не отменяет?

Отменяет.

0,4-0,6 сек

Фига у тебя винтяра.

Ответить

Номер ответа: 8
Автор ответа:
 Artyom



Разработчик

Вопросов: 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
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #10 Добавлено: 27.05.10 19:07
Считывание данных с диска выполняется несравнимо дольше чем их анализ, и здесь от способа разбиения суммарная скорость не зависит. Разумеется, если ты нигде не накосячил

Ответить

Номер ответа: 11
Автор ответа:
 Smith



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #11 Добавлено: 29.05.10 00:38
Короче просто
ТС юзал дотнэт без религиозного трепета
и великий бох фрэймворк наказал его за это :)

Ответить

Номер ответа: 12
Автор ответа:
 VβÐUηìt



Вопросов: 246
Ответов: 3333
 Web-сайт: смекаешь.рф
 Профиль | | #12
Добавлено: 30.05.10 15:29
Artyom пишет:
и здесь от способа разбиения суммарная скорость не зависит.

Ну почему... Можно например, чуть-чуть сэкономить время: считываем первые 10'000 строк, запускаем обработку отдельным потоком, тем временем считываем другие десять тысяч строк, запускаем обработку еще одним потоком и т.п. В данном случае время обработки сведется к минимому, так как время будет тратиться только на считывание ботвы с жесткого диска (ибо оброаботки, запущенные параллельно, будут завершаться гораздо быстрее), и обработка не будет задерживать считывание.

Ответить

Номер ответа: 13
Автор ответа:
 Smith



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #13 Добавлено: 30.05.10 16:35
обработка совсем не будет задерживать чтение если вгрузить всё за один раз

Ответить

Номер ответа: 14
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #14 Добавлено: 30.05.10 18:48
и обработка не будет задерживать считывание.

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

обработка совсем не будет задерживать чтение если вгрузить всё за один раз

она и так ничего не задерживает... а вот грузить в память большие объемы данных - это есть криво.

Ответить

Номер ответа: 15
Автор ответа:
 Smith



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #15 Добавлено: 30.05.10 20:33
нэтбук сцуко клава моросит
Михаил пишет:
Есть куча файлов по 1-10 мегобайт

Ну даже если и как у тебя
EROS пишет:
Размер файла получился ~31 метр

большим объемом это не назовешь
сами говорите, что мелочится с ресурсами на современных машинах неприлично

Ответить

Страница: 1 | 2 | 3 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам