|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
Что-то ищу информацию, и похоже ни PLINQ ни Parallel не умеют работать с async вызовами. Мне нужно выполнить работу, которая включает в себя кучу последовательных обращений к БД, с мелкой обработкой промежуточных результатов. Т.е. куча IO Bound операций с маленькой каплей Cpu-Bound. Ну к примеру вот тут пишут про PLINQ не умеет async (ответ дан 5 дней назад) https://stackoverflow.com/a/51600479 It does not matter, that you try to await the AsyncTask(), because ForAll() gets a plain Action and does not await the result of your AsyncTask(). А тут пишут, что класс Parallel тоже не в курсе про async https://stackoverflow.com/a/11565317 и там же предлагают задействовать TPL Dataflow - вот он мол умеет работать. Но в тоже время является очень тяжеловесным решением. Так какой выход на текущем временном отрезке ? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 17:39 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCore, 1. Почему бы всю работу не сделать в БД? 2. Если у тебя 99,999% времени есть ожидание БД, а остальное обработка в приложении, то имеет смысл проверить, будет ли польза от параллельного обращение к БД, возможно встрянешь еще сильнее по скорости. 3. Если все же есть смысл ходить в БД параллельно, то просто запусти 10-100 потоков, пусть ждут наздоровье. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 18:23 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
ЕвгенийВ, В том и суть. что нужно сделать в несколько потоков. Распараллелить и загрузить бд работой. Бд же не умеет в несколько потоков работать ? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 18:24 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
ЕвгенийВ, ну собственно я и хочу запустить 100 потоков - но, это правильно делать через async/await. А непосредственно генерацией этих сотен потоков занимаются PLINQ и Parallel. Но созданы они давно, и, как я понял, мелкософты не удосужились добавить в них поддержку async/await. А без них создавать сотни IO-Bound задач уже не комильфо. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 18:27 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreБд же не умеет в несколько потоков работать ? Ну тут смотря какая БД у тебя, odbc driver for dbf скорее всего не умеет :) ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 18:27 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
ms sql. Я имел ввиду - что я же не могу внутри T-SQL написать код который будет параллелить. Нету такого функционала в принципе. Это в C# я могу создавать потоки вручную, как и сколько мне надо. Я могу лишь запустить сотню потоков работающих с бд из клиентского приложения. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 18:30 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreЕвгенийВ, ну собственно я и хочу запустить 100 потоков - но, это правильно делать через async/await. А непосредственно генерацией этих сотен потоков занимаются PLINQ и Parallel. Но созданы они давно, и, как я понял, мелкософты не удосужились добавить в них поддержку async/await. А без них создавать сотни IO-Bound задач уже не комильфо. Исторически TPL была создана раньше async/await для распараллеливания вычислений, последние же нужны для асинхронности. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 18:34 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
ЕвгенийВ3. Если все же есть смысл ходить в БД параллельно, то просто запусти 10-100 потоков, пусть ждут наздоровье. Собственно тут есть два пути - правильный и не правильный. не правильный это Task.Run (()=> SqlConnection.Query<Model>). В этом случае потоки будут простаивать в момент этого самого Query (пользуясь терминологией Dapper.Net). правильно это что-то типа Parallel.ForEach (async x=> await SqlConnection.QueryAsync<Model>). В этом случае потоки будут освобождены на время QueryAsync. Но беда в том, что, как я понял, Parallel.ForEach (и Plinq) не знаю про async/await. Они могут только работать по неправильному пути. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 18:34 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
ЕвгенийВ, Конечно TPL появилось раньше async/await. Странно лишь то, что умные головы из Microsoft не добавляют поддержку в PLINQ и Parallel поддержку методов вида Parallel.ForEachAsync. При том что это сделали для любых маломальских классов типа File.GetAllTextAsync и прочего сразу с вводом async/await. Не пойму почему. И даже альтернативы то не сделали. Кроме огромнейшего TPL Dataflow. Тянуть его в проект ради того, чтобы один раз воспользоватся аналогом Parallel.ForEachAsync как-то не хочется. Вот и ищу, может есть какие-то другие альтернативы ? Кроме самописных велосипедов... ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 18:38 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCorems sql. Я имел ввиду - что я же не могу внутри T-SQL написать код который будет параллелить. Ну почему же, можешь ! В T-SQL что делать решает оптимизатор и каждый простенький запрос может обслуживаться кучей потоков. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 18:38 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
ЕвгенийВ, Если я правильно понимаю тут речь о распараллеливании селекта. А мне нужно запустить некую T-SQL процедуру в нескольких экземлярах. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 18:46 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCore, Сколько понаписал то. Внутри потока создавай коннект и работай. В чем проблема? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 18:47 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCore При том что это сделали для любых маломальских классов типа File.GetAllTextAsync и прочего сразу с вводом async/await. Не пойму почему. Это для тех случаев, когда Cpu-Bound не хватает, например в web highload приложении или для ГУЯ, дабы не блокировать его и не сильно напрягать программистов для этого. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 18:49 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreЕвгенийВ, Если я правильно понимаю тут речь о распараллеливании селекта. А мне нужно запустить некую T-SQL процедуру в нескольких экземлярах. Грубо говоря, если ты запустишь несколько раз долгоиграющую процедуру из разных окон например SSMS, то все запущенные будут исполняться параллельно. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 18:52 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreА тут пишут, что класс Parallel тоже не в курсе про async https://stackoverflow.com/a/11565317 и там же предлагают задействовать TPL Dataflow - вот он мол умеет работать. Но в тоже время является очень тяжеловесным решением. Там ниже предлагаются варианты на все возможные случаи "замеса" параллельности и асинхронности - RunWithMaxDegreeOfConcurrency и ForEachAsync. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 19:04 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
LRТам ниже предлагаются варианты на все возможные случаи "замеса" параллельности и асинхронности - RunWithMaxDegreeOfConcurrency и ForEachAsync. ...и еще ниже - ParallelForEachAsync ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 19:06 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreне правильный это Task.Run (()=> SqlConnection.Query<Model>). Правильный: Task.Run(()=> MyMetodAsync() ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 19:12 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCore, Кажется, что вы смешали мухи с котлетами. Чтобы понять где косяк, надо просто понять одну простую вещь. Код с асинхронными вызовами с точки зрения execution flow абсолютно синхронный. В тоже время TPL это параллельный execution flow, поэтому "уметь" async он не должен. Вполне достаточно WhenAll, который умеет await. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 19:58 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
hVosttВполне достаточно WhenAll, который умеет await. Ну а если элементов сотни, глупо же выполнять их на сотне потоков... Разумно приделать какое-то "горло". По второй ссылке из первого поста ТСа весьма привлекательным выглядит самое последнее решение, где горлышко организовано с помощью SemaphoreSlim ForEachAsyncConcurrentAn extension method for this which makes use of SemaphoreSlim and also allows to set maximum degree of parallelism Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45.
Sample Usage: Код: c# 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 22:13 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
LR, Оставлю это здесь https://docs.microsoft.com/ru-ru/dotnet/standard/asynchronous-programming-patterns/consuming-the-task-based-asynchronous-pattern ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 22:39 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
LRНу а если элементов сотни, глупо же выполнять их на сотне потоков... https://docs.microsoft.com/ru-ru/dotnet/standard/asynchronous-programming-patterns/consuming-the-task-based-asynchronous-pattern#throttling ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 22:41 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
hVostt https://docs.microsoft.com/ru-ru/dotnet/standard/asynchronous-programming-patterns/consuming-the-task-based-asynchronous-pattern#throttling Ага, получается в документации эти вопросы рассмотрены, но кто ж ее читает)) И еще, если посмотреть в Task.WhenAny , с созданием копии списка задач, то вариант с семафором может получиться и побыстрее, х.з. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 23:05 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
LRНу а если элементов сотни, глупо же выполнять их на сотне потоков... С чего их сотня если пул потоков по умолчанию настройка макс около 20 потоков. Остальные ждать будут. И писать ничего не надо. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 23:24 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
Petro123LRНу а если элементов сотни, глупо же выполнять их на сотне потоков... С чего их сотня если пул потоков по умолчанию настройка макс около 20 потоков. Остальные ждать будут. И писать ничего не надо. Ну какая разница, суть в другом - забирать все потоки из пула для одной задачи, если только она не единственная - глупо. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 23:31 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
LRНу какая разница, суть в другом - забирать все потоки из пула для одной задачи, если только она не единственная - глупо. суть нелогична. Если задача одна - зачем параллелить? Об чём топик? Как хранимку распарралелить "чтобы было"? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.08.2018, 23:39 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
Petro123, Ну короче сейчас все сделано через T-SQL процедуру. Извлекаются данные курсором и потом идет длинный алгоритм со сложной логикой со считыванием данных из других таблиц и последущими расчетами. По каждому элементу отдельно. Получается обрабатывать около 20-30 элементов в секунду. Нужно существенно увеличить эту цифру. Т.к. нужно обрабатывать архивы данных. Что я хочу сделать через перевод на C# и увеличение количества потоков, выполняющих данный алгоритм, что выльется в некую цепочку: CpuBound(мелкая обработка)+IOBound(долго)+CpuBound(мелкая обработка)+IOBound(долго)+IOBound(долго)+CpuBound(мелкая обработка). ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 10:44 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreИзвлекаются данные курсором и потом идет длинный алгоритм со сложной логикой со считыванием данных из других таблиц и последущими расчетами. Курсоры в T-SQL = тормоза. Это было подтверждено уже не раз. И способ убыстрения таких алгоритмов, как ни странно - отказ от курсоров (и скалярных UDF). Все расчеты и извлечение данных помещаются в один запрос. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 10:49 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
А тему я создал потому, что хотел понять есть ли стандартные способы от разработчиков C#. Странно стало, что PLinq и Parallel не умеют по async. Думал может чего упустил, но получается не упустил. Ну, придется воспользоватся велосипедом ForEachAsyncConcurrent, только я думаю там имеет смысл добавить ThreadPool.SetMaxThreads если maxDegreeOfParallelism задан больше Environment.ProcessorCount, что не учтено в данном методе. Иначе толку от maxDegreeOfParallelism не будет - пул потоков тупо не запустит новые задачи. Вот поэтому я и не хотел использовать велосипеды, уж разрабы C# точно не упустят важные вещи. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 10:51 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
Сон Веры ПавловныWaspNewCoreИзвлекаются данные курсором и потом идет длинный алгоритм со сложной логикой со считыванием данных из других таблиц и последущими расчетами. Курсоры в T-SQL = тормоза. Это было подтверждено уже не раз. И способ убыстрения таких алгоритмов, как ни странно - отказ от курсоров (и скалярных UDF). Все расчеты и извлечение данных помещаются в один запрос. Ну а как без алгоритмов то, в условиях когда есть алгоритмы вида if сделай то-то, else сделай длинную цепочку другого алгоритма. Упихивать это в чистый SQL слишком сложно и запутанно - через всякий там merge и прочие. Ну вот думаю проще перенести логику на C# хотя бы. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 10:53 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreНу а как без алгоритмов то, в условиях когда есть алгоритмы вида if сделай то-то, else сделай длинную цепочку другого алгоритма. Упихивать это в чистый SQL слишком сложно и запутанно - через всякий там merge и прочие. Вполне нормально. Декомпозиция решает. Сложные/громоздкие вычисления выносятся в инлайновые TVF, и используются в основном запросе посредством cross/outer apply. Поскольку функции инлайновые, то оптимизатором всё это будет собрано в один запрос с единым планом выполнения. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 11:01 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreСон Веры Павловныпропущено... Курсоры в T-SQL = тормоза. Это было подтверждено уже не раз. И способ убыстрения таких алгоритмов, как ни странно - отказ от курсоров (и скалярных UDF). Все расчеты и извлечение данных помещаются в один запрос. Ну а как без алгоритмов то, в условиях когда есть алгоритмы вида if сделай то-то, else сделай длинную цепочку другого алгоритма. Упихивать это в чистый SQL слишком сложно и запутанно - через всякий там merge и прочие. Ну вот думаю проще перенести логику на C# хотя бы. Да запросто - от CASE в качестве полей выбора, до UNION нескольких наборов, удовлетворяющих разным условиям. Настоятельно рекомендую Вам об этом подумать ... ну или назовите приложение, над которым работаете, - чтобы нечаянно с ним не познакомиться ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 11:01 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
мне проще на C#. тут видимо вопрос опыта в конкретных тенологиях. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 11:03 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreмне проще на C#. тут видимо вопрос опыта в конкретных тенологиях.именно батенька. Вопрос где размещать БЛ бизнес логику. Он флеймовый. Можно в бд на его ЯП. Можно в АппСервере. Ты выбрал второе т.к. больше знаешь шарп. Логично). ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 11:11 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
Сон Веры ПавловныПоскольку функции инлайновые, то оптимизатором всё это будет собрано в один запрос с единым планом выполнения.в этом я не силен. Я либо оптимизатор бд и его большая хранимка. Либо ОРМ и тогда оптимизатор голова разработчика). Конечно, при аналитике как бы и ОРМ уже не подходит. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 11:14 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreТ.к. нужно обрабатывать архивы данных.сделайте для архива денормализацию и olap\oltp. Обычно архивы для ускорения как раз отдельно. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 11:18 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
Здесь есть еще один нюанс: когда данные собираются единым запросом, сервер сам обеспечивает консистентность этих данных (либо механизмом блокировок, либо механизмом IRCS). Если зависящие друг от друга данные собираются кучей атомарных запросов в параллельных потоках (и сессиях), есть достаточно неплохой шанс смоделировать ситуацию грязного чтения. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 11:22 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreчто выльется в некую цепочку:при увлечении цепочками будут потери при переключении контекста. Со школы известно что 2 потока не быстрее в 2 раза одного. А например, денормализация ускорит вам в 10 раз. IMHO ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 11:24 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
Сон Веры Павловныгрязного чтения.ну, у него архив вроде. Данные статичны. Но конечно, один запрос без курсоров это идеал. Это обычно в ветке БД пробуют написать. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 11:27 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
Petro123WaspNewCoreчто выльется в некую цепочку:при увлечении цепочками будут потери при переключении контекста. Со школы известно что 2 потока не быстрее в 2 раза одного. А например, денормализация ускорит вам в 10 раз. IMHO Petro123Сон Веры Павловныгрязного чтения.ну, у него архив вроде. Данные статичны. Но конечно, один запрос без курсоров это идеал. Это обычно в ветке БД пробуют написать. Написать такую сложную логику для меня будет сложновато. Тем более с OLTP и пр. Мне проще перенести на C#. Понятно, что параллельность не увеличит производительность прям ровно в нужное количество потоков, см. Закон Амдала . Но я думаю увеличение будет достаточно существенным. Раз этак в 1.87 с двух потоков и т.д. Со 100 потоков может выжмется ускорение раз в 70. Полагаю для моей текущей задачи такой производительности хватит за глаза. Если потом упрусь в потолок и его все равно будет не хватать (а это вряд ли произойдет в ближайшие годы) подключу спеца по SQL, чтобы он уже ворочал OLPT и пр. Но это слишком далекие планы. Что касается грязного чтения.. хм. Вряд ли. Работа идет с уже готовыми статичными данными. Берется родительская запись и ее обрабатывает один поток. Который запрашивает подчиненные сущности и их обрабатывает, с последующей заливкой в другие таблицы. Пересечений и дедлоков в принципе не должно быть. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 11:45 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
Или это не Закон Амдала утверждает, что накладные расходы при распараллеливании вычислений уменьшают общую производительность. Забыл, не важно в общем ) ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 11:49 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCore Берется родительская запись и ее обрабатывает один поток. Который запрашивает подчиненные сущности и их обрабатывает, с последующей заливкой в другие таблицы. Пересечений и дедлоков в принципе не должно быть. Ну тут прямо напрашивается select->insert. без всяких await/async ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 12:12 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreСо 100 потоков может выжмется ускорение раз в 70.сомневаюсь. По правилом нужна демка ПРОТОТИП. Ставьте sleep() вместо БЛ и уже завтра, в выходной отпишитсь во сколько раз 20 потоков SELECT record быстрее чем курсор в базе. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 12:51 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
ЕвгенийВWaspNewCore Берется родительская запись и ее обрабатывает один поток. Который запрашивает подчиненные сущности и их обрабатывает, с последующей заливкой в другие таблицы. Пересечений и дедлоков в принципе не должно быть. Ну тут прямо напрашивается select->insert. без всяких await/asyncон хочет 100 select по одной записи одновременно в базу. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2018, 12:52 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreСтранно стало, что PLinq и Parallel не умеют по async. Видимо, научить непросто. Представьте, к очереди элементов еще первоначально не опоточенных, добавится очередь готовых к продолжению после await. Части (или всем) из этих последних нужно продолжить в первоначальном потоке. А еще бывают и такие асинхи , которые не умеют продолжать в чужом потоке (несмотря на ConfigureAwait(false)). ... |
|||
:
Нравится:
Не нравится:
|
|||
18.08.2018, 11:27 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
LR Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45.
Кстати, по поводу этой реализации, которая встречается множество раз (автор знатно постарался в распространении своего говнокода), должен сказать. Не нужно использовать эту реализацию у себя, так как при достаточно большом количестве элементов тупо пожирает память и выход может быть более медленным, чем хотелось бы. В общем, не нужно бездумно копировать всякую дичь со стеков :) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.08.2018, 01:02 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
hVosttНе нужно использовать эту реализацию у себя, так как при достаточно большом количестве элементов тупо пожирает память и выход может быть более медленным, чем хотелось бы. А можете объяснить в чем проблемы ? Я не вижу критичных, метод выглядит вполне юзабельным. А значит я чего-то не понимаю в async/await. Нужно срочно это исправить, просвятите :) И что значит "выход может быть более медленным" ? Какого порядка цифры ? Если речь о лишних микросекундах из-за ожиданий await semaphoreSlim.WaitAsync() то не вижу тут проблем, потери в десяток микросекунд я не считаю - такой сверхоптимизации мне не требуется. У меня всего лишь пара мелких замечаний: 1. добавить ConfigureAwait(false) везде. 2. Код: c# 1.
Начиная с 4.5 фреймворка уже не нужно преобразовывать в массив. WhenAll с тех пор принимает IEnumerable. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.08.2018, 11:43 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCore, Проблема здесь: LR Код: c# 1.
Если через аргумент функции enumerable будет прокачано миллиард элементов, в памяти останутся миллиард экземпляров Task, да и эвейтить этот миллиард то ещё удовольствие. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.08.2018, 11:59 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
hVostt, Да, я думал на этот момент. Но это стандартная проблема с кодом вообще - не создать случайно List на триллиард записей. Полагаю, что проблема как раз из-за необходимости передать в Task.WhenAll массив. Можно немного оптимизировать - заменить Код: c# 1.
на Код: c# 1.
- заменить Код: c# 1.
на Код: c# 1.
не смотрел код Task.WhenAll, но если там что-то типа Код: c# 1. 2.
то должно работать гладко. Но в принципе на не очень больших коллекциях ( ну чтобы не растить List до миллиардов) и так будет работать. В принципе конкретно в своем решении я разбиваю работы на пакеты по ~1000 элементов, так, что особых рисков не будет. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.08.2018, 12:14 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreМожно немного оптимизировать ...или взять правильный, корректно работающий код без блокирующих коллекций https://docs.microsoft.com/ru-ru/dotnet/standard/asynchronous-programming-patterns/consuming-the-task-based-asynchronous-pattern#throttling :) не думаю, что BlockingCollection в контексте отсутствия параллелизма, а это именно так на таск эвейте, хорошая идея, скорее очень плохая. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.08.2018, 13:48 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCoreНо в принципе на не очень больших коллекциях ( ну чтобы не растить List до миллиардов) и так будет работать. В принципе конкретно в своем решении я разбиваю работы на пакеты по ~1000 элементов, так, что особых рисков не будет. Это заряженное ружьишко, которое может очень больно может садануть и прострелить ногу. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.08.2018, 13:48 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
WaspNewCore не смотрел код Task.WhenAll, но если там что-то типа Код: c# 1. 2.
Там такая мутота Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.08.2018, 15:49 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
Вообще, по хорошему, нужна система с обратной связью, т. е. на каждой итерации увеличиваешь количество потоков/тасков, до тез пор, пока растет итоговая производительность и не увеличиваешь/понижаешь когда итоговая производительность начинает падать. await/async тут тебе не нужно. Ну и как правило нужно улучшить производительность БД, созданием индексов/статистик/мат. view и протиранием монитора. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.08.2018, 16:03 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
ЕвгенийВawait/async тут тебе не нужно При наличии I/O весьма полезен. Систему с обратной связью покажи ) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.08.2018, 16:12 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
ЕвгенийВ, Интересно. Какой прок тогда принимать IEnumerable, если все сводится к ToArray. Наверное ради того, чтобы собрать результат работы всех тасков, чтобы потом выбросить AggregateException. Но даже в этом случае не лучше ли было работать с List в который динамически добавлять каждую задачу после ее ожидания. Ну. Не нам судить профи, скорее всего причина все таки у них есть, просто нужно изучать код. Причина скорее всего есть, я верю в профессионализм разрабов C#. В любом случае, как я сказал выше, на достаточно небольшом числе задач, указанный метод вполне рабочий. Буду его пока придерживаться. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.08.2018, 16:13 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
hVostt Систему с обратной связью покажи ) Как то так. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.08.2018, 16:39 |
|
Как делать кучу параллельных IO-Bound операций ?
|
|||
---|---|---|---|
#18+
ЕвгенийВ, спасибо, потестирую в ближайшее время :) ... |
|||
:
Нравится:
Не нравится:
|
|||
21.08.2018, 11:05 |
|
|
start [/forum/topic.php?all=1&fid=20&tid=1399268]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
126ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
89ms |
get tp. blocked users: |
1ms |
others: | 282ms |
total: | 539ms |
0 / 0 |