Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

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

 

  Вопрос: Substring, left, right, mid и скорость в цикле Добавлено: 26.05.10 00:09  

Автор вопроса:  Михаил

Ответить

  Ответы Всего ответов: 31  

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



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #16 Добавлено: 30.05.10 20:57
ИМХО, самый фифектный способ ускорить обработку дофига небольших файлов это:

1 прога должна плодить анализирующие потоки, по одному на файл
2 файлы хранить на многорайде, на накопителях с оптоканалами
3 исполнять это всё имеет смысл на машине с дюжиной ядер

тогда можно будет иметь результаты анализа двух гигов данных :)

Ответить

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



Вопросов: 58
Ответов: 4255
 Профиль | | #17 Добавлено: 31.05.10 07:50
у меня парсинг 30 метров (500 000 строк) занял 0,4-0,6 сек.. какой смысл изобретать велосипед?

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

даже если и так, но зачем грузить 30 метров ненужных данных (фактически мусора) в память, если можно обработать построчно через Reader? и достаточно быстро и ресурсы не откусили..

Ответить

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



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #18 Добавлено: 31.05.10 11:37
VBD пишет:
Ну почему... Можно например, чуть-чуть сэкономить время: считываем первые 10'000 строк, запускаем обработку отдельным потоком, тем временем считываем другие десять тысяч строк, запускаем обработку еще одним потоком и т.п. В данном случае время обработки сведется к минимому, так как время будет тратиться только на считывание ботвы с жесткого диска (ибо оброаботки, запущенные параллельно, будут завершаться гораздо быстрее), и обработка не будет задерживать считывание.


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

Но считаю нужным повториться - время которое тратится на обработку одной строки не может быть каким-либо образом сравнимо с временем, которое тратится на чтение строки, поэтому эти манипуляции не дадут ровным счетом ничего.
Другое дело если обработка стркои длительная операция. Например, строка это URL, и нужно каждый URL запросить с сайта. Или еще что-то в этом роде.

============

На небольших файлах (до 500 МБ) я бы просто грузил файл в память через ReadAllLines - это делатеся одной строчкой, а с массивами очень удобно дальше работать через LinQ
На больших файлах написал бы реализацию IEnumerable для перебора строк через StreamReader, и опять же работать дальше через LinQ

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

Ответить

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



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #19 Добавлено: 31.05.10 12:11
ИМХО, самый фифектный способ ускорить обработку дофига небольших файлов это:

1 прога должна плодить анализирующие потоки, по одному на файл
2 файлы хранить на многорайде, на накопителях с оптоканалами
3 исполнять это всё имеет смысл на машине с дюжиной ядер

тогда можно будет иметь результаты анализа двух гигов данных :)


Во-первых, по одному потоку на каждый файл запускать нельзя! Как вообще можно было такое придумать?
При существенном кол-ве файлов (больше тысячи я имею в виду) программа просто ляжет. Предел лежит где-то на 1500-1700 потоков, по достижению этого кол-ва программа практически перестает работать.

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

Задача обработки большого кол-ва маленьких файлов, как это ни стрнно, проще всего реализуется "в лоб" и ничего здесь изобретать не нужно. Тем более что 2 ГБ данных можно даже полностью в память загрузить и держать.

Делал обработку csv файла весом чуть больше 1 гб. Через какую-то библитоеку с codeproject.com в потоковом режиме построчно (по одной записи) считывал данные из файла, загружал их в структуру, которую сохранял в памяти.
Дальше через LinQ делались группировки и аггрегация по этому куску данных в памяти. Это именно решение в лоб, работало несколько минут, точно уже не помню, но быстродействия было более чем достаточно для разовой задачи.

Интереснее было бы сделать слияние и группировку данных по определенным критериям из 10 csv файлов с неотсортироваными данными каждый по 2 ГБ. Сразу говорю, довольно просто задачу можно решить на SSIS.

Ответить

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



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #20 Добавлено: 31.05.10 22:31
Бляя, Артем я фшоке...
Так хотелось выставить меня нубом, что даже посчитать некогда?
Грубо делим два гига на файлики по десять метров.
Мне сказать скока нужно будет потоков?
Ну пусть даже по пять метров, всё равно тока 400 потоков, НУ НИКАК НЕ ТЫЩУ И СОВСЕМ НИКАК НЕ БОЛЕЕ!
Поюзаешь хранилище похожее на то, о котором я там упоминал, вот тогда поговорим о хранении файлов на отдельных винтах.
Тут Эрос против загрузки 10 метров в память, вот лучше с ним поспорь.
И главное твои 2 гига ему не мешают, а мои 10 метров это криво.
У вас обоих кривой нацизм чтоли в мозгах?

Ответить

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



Вопросов: 58
Ответов: 4255
 Профиль | | #21 Добавлено: 31.05.10 23:23
И главное твои 2 гига ему не мешают

Очень даже мешают, я всегда был против бездумного расхода ресурсов..

Ответить

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



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #22 Добавлено: 31.05.10 23:32
Ну тады сори

Ответить

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



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #23 Добавлено: 31.05.10 23:36
Вот я тоже ужасно воспротивился излишнему поеданию ресурсов.
Знаю, что это долбанный перфекционизм, а фсё равно душе покоя нет :)

Ответить

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



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #24 Добавлено: 31.05.10 23:44
Есть один простенький алгоритм рисования пламени, так ради макс. фрэймрэйта я его в условный цикл фсунул, ну и получил загрузку ядра на 100%, но даже на ееерс ~40 фпс, ну и радовался, думал, ведь не часто народ в абаут лазиет, а так в коем разе пусть узреет

Ответить

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



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #25 Добавлено: 31.05.10 23:49
Но в последнее время, чето стало ужасно жалко съеденного в пустую ядра, воткнул таймер.
И фпс ~65 и проц свободен и я счастлив :).
А всё эти байты байты килобайты

Ответить

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



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #26 Добавлено: 01.06.10 03:41
Smith пишет:
Бляя, Артем я фшоке...
Так хотелось выставить меня нубом, что даже посчитать некогда?

Не вижу смысла тебя как-то выставлять, просто твои сообщения говорят сами за себя.

Так хотелось выставить меня нубом, что даже посчитать некогда?
Грубо делим два гига на файлики по десять метров.
Мне сказать скока нужно будет потоков?
Ну пусть даже по пять метров, всё равно тока 400 потоков, НУ НИКАК НЕ ТЫЩУ И СОВСЕМ НИКАК НЕ БОЛЕЕ!

Откуда берутся цифры 2 ГБ и 10 МБ? А если 20 ГБ бить на файлы по 1 МБ?
400 - это совсем не "дофига файлов" про котоыре шла речь, 2000 - это уже условно может быть дофига. 20000 - определенно дофига. Субъективно, по крайней мере. Если у тебя другое, нужно было указать что речь идет об обработке нескольких сотен файлов. Что делает предложеный способ условно рабочим, но не делает быстрым.

Поюзаешь хранилище похожее на то, о котором я там упоминал, вот тогда поговорим о хранении файлов на отдельных винтах.

Я не работал сетевым хранилищем, состоящим из нескольких сотен дисков. И почти никто не работал.

Это не мешает мне говорить параллельное чтение нескольких файлов одновременно будет работать быстрее чем последовательное только в том случае, если файлы хранятся на разных физических дисках.

По той причине что на жестких дисках операции последовательного досутпа работают быстрее чем операции случайного доступа. Это справедливо для жесткого диска, установленого в ноутбуке, и жестого диска, установленого в сетевом хранилище.
Это не касается твердотельных накопителей, в которых операции случайного доступа работают так же быстро как и операции последовательного (при этом почти не использующиеся в сетевых хранилищах из-за высокой стоимости и ряда ограничений, в том числе на кол-во циклов перезаписи).

В некоторых случаях параллельное чтение с RAID массива (5/6) может быть быстрее последовательного. Но для этого должны выполниться несколько условий. Во-первых, файл должен быть размера, примерно равному размеру блока. Во-вторых, файлы должны оказаться на разных физических дисках массива. Кол-во потоков должно быть примерно равным кол-во дисков в массиве.

Насколько я знаю, в RAID5 обычно ставят не больше 10 дисков, и выделять по одному диску для каждого файла весом в 10 МБ чтоб операции чтения выполнялись быстрее не совсем выгодно.

Тут Эрос против загрузки 10 метров в память, вот лучше с ним поспорь.
И главное твои 2 гига ему не мешают, а мои 10 метров это криво.

Я не слышал чтоб он что-то говорил про "мои 2 гига". Да и задача проще всего решалась загрузкой всех данных в память (выполнять сортировку 2 гб данных на диске когда есть возможность сортировать в памяти - не очень хорошая идея на самом деле).

У вас обоих кривой нацизм чтоли в мозгах?

А у тебя какой?

Ответить

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



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #27 Добавлено: 01.06.10 03:44
Есть желающие провести бенчмарк на чтение 400 файлов по 10 МБ в параллельном/последовательном режиме? От "параллельщиков" хотелось бы увидеть 2 варианта реализации, с использвоанием 400 потоков и с использвоанием асинхрнного ввода-вывода.

Ответить

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



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #28 Добавлено: 02.06.10 22:00
Откуда беруться цифры 2 гига и 10 метров?
Это твои посты говорят сами за себя, а мои говорят только то, что я хочу ими выразить :).
Согласен, что "дофига файлов" какбы подразумевает больше чем 400, но как ты сам заметил это субъективно, и только тебя это могло вдохновить на проведение расчетов ради разоблачения шуточной идеи.
Бэнчмарк предложи Эросу, у вас прямо противоположные взгляды на самый важный вопрос темы.
В моей голове только здоровый патриотизм.

Ответить

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



ICQ: adamis@list.ru 

Вопросов: 153
Ответов: 3632
 Профиль | | #29 Добавлено: 02.06.10 22:12
И как всегда ты трудолюбиво составил ТЗ, а какже со сроками? УЖЕ ПИШУ! :-D

Ответить

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



Вопросов: 246
Ответов: 3333
 Web-сайт: смекаешь.рф
 Профиль | | #30
Добавлено: 03.06.10 20:15
Artyom пишет:
Но считаю нужным повториться - время которое тратится на обработку одной строки не может быть каким-либо образом сравнимо с временем, которое тратится на чтение строки, поэтому эти манипуляции не дадут ровным счетом ничего.
Другое дело если обработка стркои длительная операция. Например, строка это URL, и нужно каждый URL запросить с сайта. Или еще что-то в этом роде.

Вот именно поэтому я предложил считывать по 10'000 строк. Время считывания, коненчо, все равно дольше, чем обработка, но все равно, если она идет параллельно со считыванием хоть какое-то время, то время экономится. Вася остается неоптимальной только в первый раз, когда еще первый пакет не считали. А дальше - просто обрабатывается первый пакет, в это время считывается второй, потом обрабатывается, пока считывается третий, и т.п. Если время обработки намного меньше времени считывания, то васю еще и к тому же не неужно особо синхронизировать (осторожно, говнокот). То есть формально это выглядит так:
Вася 1: параллельная обработка с пакетами - считываем 10'000 строк, обрабатываем, праллельно считываем другие 10'000 строк, как считали - опять запускаем ассинхронную обработку и так далее:
По горизонтали типа время -->
  1. 111111222222333333444444555555  'Чтение
  2.       1     2     3     4     5 'Обработка

Тут цифрами обозначены пакеты, пробелами - ожидание потока, количество цифр - условная длительность обработки. Сравниваем с тупым последовательным перебором чтение-обработка-чтение-обработка и т.п.
Вася 2: Тупо последовательно считываем и обрабатываем (при условии, что время обработки и считывания то же, что и в Васе 1
Время -->
  1. 11111112222222333333344444445555555

Видно, что Вася 1 делается быстрее, и, видимо, этот отрыв будет сокращаться с увеличением соотношения длительность чтения/обработки. Смекнули?

Ответить

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

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



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