[Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 02:32
Оценка: -2 :)
Что-то давно этюдов не было. Не знаю тянет ли это на этюд, но попробую.

Сразу код: синхронный вариант и асинхронный вариант метода (SyncMethod и AsyncMethod):

  Синхронный
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp29
{
    class Program
    {
        static void SyncMethod(int i)
        {
            Task.Delay(1).Wait(); // Много разных асинхронных вызовов обессинхрониваем - не комильфо...
            Task.Delay(1).Wait();

            // Это убрать нельзя - эмуляция вызова асинхронного метода, который мы изменить не можем.
            Thread.Sleep(1000);

            Console.WriteLine(i);
        }

        static async Task Main(string[] args)
        {
            var sw = new Stopwatch();

            Console.WriteLine("Start");

            sw.Start();

            var tasks = Enumerable
                .Range(0, 1000)
                .Select(i => Task.Factory.StartNew(() => { SyncMethod(i); }, TaskCreationOptions.LongRunning));

            await Task.WhenAll(tasks);

            sw.Stop();

            Console.WriteLine("Done!");
            Console.WriteLine($"ElapsedMilliseconds={sw.ElapsedMilliseconds}");
        }
    }
}


и

  Асинхронный
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp29
{
    class Program
    {
        static async Task AsyncMethod(int i)
        {
            await Task.Delay(1); // Много разных асинхронных вызовов...
            await Task.Delay(1);

            // Это убрать нельзя - эмуляция вызова асинхронного метода, который мы изменить не можем.
            Thread.Sleep(1000);

            Console.WriteLine(i);
        }


        static async Task Main(string[] args)
        {
            var sw = new Stopwatch();

            Console.WriteLine("Start");

            sw.Start();

            var tasks = Enumerable
                .Range(0, 1000)
                .Select(AsyncMethod);

            await Task.WhenAll(tasks);

            sw.Stop();

            Console.WriteLine("Done!");
            Console.WriteLine($"ElapsedMilliseconds={sw.ElapsedMilliseconds}");
        }
    }
}


Метод внутри себя имеет синхронный длительный вызов (эмулируем с помощью Thread.Sleep), который во внешней библиотеке и переписать который в асинхронном варианте мы не можем.

Итак, если запустить код — то увидим, что синхронный вариант отработает за 1-2 секунды а асинхронный — около 1 минуты (примерно, не ждал до конца). Но есть минус — в синхронном варианте внутри мы вызываем внешние асинхронные методы и каждый раз вынуждены их обессинхронивать — что не гуд.

Вопрос: как сделать, чтобы асинхронный метод отрабатывал так же быстро?
Отредактировано 30.09.2021 10:30 Shmj . Предыдущая версия . Еще …
Отредактировано 29.09.2021 9:26 Shmj . Предыдущая версия .
Отредактировано 29.09.2021 2:33 Shmj . Предыдущая версия .
Re[12]: [Этюд] - синхронный vs асинхронный
От: Sharov Россия  
Дата: 01.10.21 20:23
Оценка: 13 (2)
Здравствуйте, Serginio1, Вы писали:


S>>Что жалко что ли на 64 битке она практически бесконечна.

S> Проблема не в памяти, а в создании и переключении потоков.
S> И не забывай в твоем варианте метод практически не использует данных, а вот если будет использовать стек то он и физически будет расти.
S>То есть ты сознательно тормозишь свое приложения. Вместо того что бы при большом одновременном количестве запросов ставить их в очередь ты запускаешь новые или берешь древние потоки.
S>Там и кэш процессора сбрасывается.

По ссылке не ходил, но речь идет о процессах, а не о потоках -- потоки как раз придумали, чтобы не сбрасывать
кэш и т.п. Т.е. переключение процессов дорого, а потоков в процессе -- нет.
Кодом людям нужно помогать!
Re[9]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 29.09.21 10:58
Оценка: +2
Здравствуйте, Shmj, Вы писали:

S>Так же из этого же метода приходится вызывать синхронные.


S>Что же делать?


S>> Ты внутри задачи которая лонг вызываешь асинхронный код который внутри в итоге и вызывает Thread.Sleep(1000)


S>Предлагайте решение.

Тут и так понятно если ты вызваешь долгий синхронный код, то и работай с ним синхронно.
Асинхронный код не поможет, а только засрет пул потоков. Или выделяй отдельно долгий синхронный метод в Task c LongRunning

В данном случае
 await Task.Factory.StartNew(() =>
                {
                   Thread.Sleep(1000);
                }, TaskCreationOptions.LongRunning);


class Program
    {
        static async Task AsyncMethod(int i)
        {
            await Task.Delay(1); // Много разных асинхронных вызовов...
            await Task.Delay(1);

            // Это убрать нельзя - эмуляция вызова асинхронного метода, который мы изменить не можем.
            //Thread.Sleep(1000);
            await Task.Factory.StartNew(() =>
                {
                   Thread.Sleep(1000);
                }, TaskCreationOptions.LongRunning);

            Console.WriteLine(i);
        }

        static void Main(string[] args)
        {
            for (int i = 0; i < 1000; i++)
            {
                int iCopy = i;

                // Вариант 2: асинхронный метод отрабатывате медленно (TaskCreationOptions.LongRunning не применяется)
                Task.Factory.StartNew(async () =>
                {
                    await AsyncMethod(iCopy);
                });
            }


            Console.ReadKey();
        }
    }
и солнце б утром не вставало, когда бы не было меня
Отредактировано 30.09.2021 6:54 Serginio1 . Предыдущая версия . Еще …
Отредактировано 29.09.2021 11:07 Serginio1 . Предыдущая версия .
Отредактировано 29.09.2021 11:06 Serginio1 . Предыдущая версия .
Отредактировано 29.09.2021 11:04 Serginio1 . Предыдущая версия .
Re[4]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 01.10.21 09:22
Оценка: :))
Здравствуйте, Serginio1, Вы писали:

S> Ну да. Пул из 1000 потоков это коронное решение?

S>По моему мое решение с профайлером намного оптимальнее!

А чем плохо пул из 1 млн. потоков? Они же не будут создаваться без необходимости?
Re[5]: [Этюд] - синхронный vs асинхронный
От: alexander_r  
Дата: 30.09.21 11:21
Оценка: 20 (1)
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, alexander_r, Вы писали:


S>>>...Синхронная версия отрабатывает 1-2 сек., асинхронная 1-2 мин.

_>>а как вы время замеряете, покажите весь код??

S>Там и так все понятно, разница на порядки. Ну могу дописать ожидание завершения всех задач, но это ничего не изменит.


не знаю откуда у вас там разица на порядок
у меня ваш синхронный метод и тот что переделал Serginio1 выполняется за одинаковое время ~7.5сек
        static void SyncMethod(int i)
        {
            Task.Delay(1).Wait(); // Много разных асинхронных вызовов обессинхрониваем - не комильфо...
            Task.Delay(1).Wait();

            // Это убрать нельзя - эмуляция вызова асинхронного метода, который мы изменить не можем.
            Thread.Sleep(1000);

            Console.WriteLine(i);
        }
        static async Task AsyncMethod(int i)
        {
            await Task.Delay(1); // Много разных асинхронных вызовов...
            await Task.Delay(1);

            // Это убрать нельзя - эмуляция вызова асинхронного метода, который мы изменить не можем.
            //Thread.Sleep(1000);
            await Task.Factory.StartNew(() =>
            {
                Thread.Sleep(1000);
            }, TaskCreationOptions.LongRunning);

            Console.WriteLine(i);
        }


        static async Task Main(string[] args)
        {
            var sw = new Stopwatch();

            Console.WriteLine("Start");

            sw.Start();

            //var tasks = Enumerable
            //    .Range(0, 1000)
            //    .Select(i => Task.Factory.StartNew(() => { SyncMethod(i); }, TaskCreationOptions.LongRunning));

            var tasks = Enumerable
                .Range(0, 1000)
                .Select(i => AsyncMethod(i));

            await Task.WhenAll(tasks);

            sw.Stop();

            Console.WriteLine("Done!");
            Console.WriteLine($"ElapsedMilliseconds={sw.ElapsedMilliseconds}");

            Console.ReadKey();
        }


если добавить ConfigureAwait(false) то 7.1 сек
Re[7]: [Этюд] - синхронный vs асинхронный
От: Danchik Украина  
Дата: 01.10.21 16:24
Оценка: 8 (1)
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, Danchik, Вы писали:



S>>>А чем плохо пул из 1 млн. потоков? Они же не будут создаваться без необходимости?

D>>Один поток — 4MB на стек для x64.

S>Вроде бы 1Мб всегда был? Или в core что-то поменялось?


1MB для x32.
Re: [Этюд] - синхронный vs асинхронный
От: pilgrim_ Россия  
Дата: 30.09.21 16:27
Оценка: 3 (1)
Здравствуйте, Shmj, Вы писали:

S>Сразу код: синхронный вариант и асинхронный вариант метода (SyncMethod и AsyncMethod):


S>Итак, если запустить код — то увидим, что синхронный вариант отработает за 1-2 секунды а асинхронный — около 1 минуты (примерно, не ждал до конца). Но есть минус — в синхронном варианте внутри мы вызываем внешние асинхронные методы и каждый раз вынуждены их обессинхронивать — что не гуд.


S>Вопрос: как сделать, чтобы асинхронный метод отрабатывал так же быстро?


Установить мин. кол-во потоков в пуле в 1000 (ThreadPool.SetMinThreads). Это не бесплатно ессн, но если очень надо .
Связанно в политикой создания новых потоков в пуле, по умолчанию насколько я помню когда кол-во потоков в пуле превышает некоторое значение (где-то кол-во ядер * на некоторую константу), то добавление нового потока в пул происходит с некоторой задержкой (если память не изменяет чуть ли не секунду), и возможно эта задержка даже динамически увеличивается в зависимости от текущего размера пула.

ps: так было в большом .NET, насчёт Core хз.
Re[3]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 29.09.21 09:20
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>>А почему AsyncMethod(iCopy).Wait();

S>>а не await AsyncMethod(iCopy)
S>>https://docs.microsoft.com/ru-ru/dotnet/csharp/language-reference/proposals/csharp-7.1/async-main

S>Без разницы — это проблему не решит.

И зачем там отдельный Task.Factory.StartNew и тем более без LongRunning

То есть ты уже пробовал?
Там LongRunning запускает отдельные потоки для каждой задачи. 1000 потоков при переключении могут и тормозить.
и солнце б утром не вставало, когда бы не было меня
Отредактировано 29.09.2021 9:23 Serginio1 . Предыдущая версия . Еще …
Отредактировано 29.09.2021 9:22 Serginio1 . Предыдущая версия .
Re[3]: [Этюд] - синхронный vs асинхронный
От: paradok  
Дата: 29.09.21 13:43
Оценка: :)
Здравствуйте, Shmj, Вы писали:

S>Конечно итоговое исполнение всех задач.


да, не ожидал, действительно тормоз, ... получается async какие-то ущербные?
И что делать?
Re[25]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 29.09.21 14:22
Оценка: :)
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>>>Каким образом?

S>> Заверни весь синхронный код в Task с LongRunning

S>Если вызовов синхронных методов много (чередуются с async) и как долго они исполняются — не определено (зависит от данных) — предлагаете заворачивать каждый в отдельности? Как завернуть 1 раз для всех — вот в чем вопрос.

Ждать развития PGO, аналогом HotSpot
https://github.com/dotnet/runtime/blob/main/docs/design/features/DynamicPgo.md
и солнце б утром не вставало, когда бы не было меня
Re[4]: [Этюд] - синхронный vs асинхронный
От: paradok  
Дата: 30.09.21 09:56
Оценка: :)
Здравствуйте, alexander_r, Вы писали:

_>Здравствуйте, Shmj, Вы писали:


S>>...Синхронная версия отрабатывает 1-2 сек., асинхронная 1-2 мин.

_>а как вы время замеряете, покажите весь код??

там же номер запуска — т.е. когда появляется на экране 999 тогда и конец.
ну или когда останавливается визуально мельтешение цифер в консоли.

Для усиления эффекта можно задержку не 1 сек а 10 сек сделать

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

У меня начинаются тормоза с i=10 ! не 1000 а с 10 !!
Это вообще крест а асинках — их нельзя юзать если может вызваться больше 10 обработчиков одновременно?
Отредактировано 30.09.2021 10:06 paradok . Предыдущая версия .
Re[7]: [Этюд] - синхронный vs асинхронный
От: Ночной Смотрящий Россия  
Дата: 30.09.21 11:00
Оценка: :)
Здравствуйте, Shmj, Вы писали:

S>Добавил в стартовом сообщении.


Вынудил запустить. Переписал чтобы копипастой не заниматьсся:
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace SyncAsync
{
    static class Program
    {
        static async Task AsyncMethod(int i)
        {
            await Task.Delay(1); // Много разных асинхронных вызовов...
            await Task.Delay(1);

            // Это убрать нельзя - эмуляция вызова асинхронного метода, который мы изменить не можем.
            Thread.Sleep(1000);

            Console.WriteLine(i);
        }

        static void SyncMethod(int i)
        {
            Task.Delay(1).Wait(); // Много разных асинхронных вызовов обессинхрониваем - не комильфо...
            Task.Delay(1).Wait();

            // Это убрать нельзя - эмуляция вызова асинхронного метода, который мы изменить не можем.
            Thread.Sleep(1000);

            Console.WriteLine(i);
        }


        private static async Task RunAsync(string name, Func<int, Task> action)
        {
            var sw = new Stopwatch();

            Console.WriteLine($"Start {name}");

            sw.Start();

            var tasks = Enumerable
                .Range(0, 1000)
                .Select(AsyncMethod);

            await Task.WhenAll(tasks);

            sw.Stop();

            Console.WriteLine($"Done. ElapsedMilliseconds={sw.ElapsedMilliseconds}");
        }

        static async Task Main()
        {
            await RunAsync("Sync", i => Task.Factory.StartNew(() => SyncMethod(i), TaskCreationOptions.LongRunning));
            await RunAsync("Async", async i => await AsyncMethod(i));
        }
    }
}

Первый варинт 38 сек, второй — 22 секунды. Что вполне логично, учитывая что размер пула воркер-потоков все таки поменьше 1000 единиц, в отличие от твоей 1 секунды на все потоки, каждый из которых блокируется на секунду.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[8]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 30.09.21 11:09
Оценка: +1
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, Shmj, Вы писали:


S>>Добавил в стартовом сообщении.


НС>Вынудил запустить. Переписал чтобы копипастой не заниматьсся:

НС>



НС>        private static async Task RunAsync(string name, Func<int, Task> action)
НС>        {
НС>            var sw = new Stopwatch();

НС>            Console.WriteLine($"Start {name}");

НС>            sw.Start();

НС>            var tasks = Enumerable
НС>                .Range(0, 1000)
НС>                .Select(AsyncMethod);

НС>            await Task.WhenAll(tasks);

НС>            sw.Stop();

НС>            Console.WriteLine($"Done. ElapsedMilliseconds={sw.ElapsedMilliseconds}");
НС>        }


НС>

А где action применяется?
и солнце б утром не вставало, когда бы не было меня
Re[8]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 30.09.21 11:10
Оценка: :)
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Первый варинт 38 сек, второй — 22 секунды. Что вполне логично, учитывая что размер пула воркер-потоков все таки поменьше 1000 единиц, в отличие от твоей 1 секунды на все потоки, каждый из которых блокируется на секунду.


Вы что решарпер не используете? У вас же описка — передаете action но забываете его задействовать.

Рекомендую пользоваться профессиональными инструментами, чтобы не совершать таких ошибок.
Re[8]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 30.09.21 12:03
Оценка: :)
Здравствуйте, alexander_r, Вы писали:

_>т.е проблемы с производительностью нет, проблема в уродстве??


Выбор из двух: или тормоза или уродство.

В синхронном варианте уродства даже меньше.

Однако же есть способ, как минимум 1, как избежать уродства. Пока жду, может кто-то еще что-то лучшее предложит.
Отредактировано 30.09.2021 12:03 Shmj . Предыдущая версия .
Re[2]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 30.09.21 14:25
Оценка: +1
Здравствуйте, Danchik, Вы писали:

D> или поправьте коментарий что, вы делаете эмуляцию Синхронного вызова.

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

 await Task.Factory.StartNew(() =>
            {
                Thread.Sleep(1000);
            }, TaskCreationOptions.LongRunning);


Не красиво
и солнце б утром не вставало, когда бы не было меня
Re[2]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 30.09.21 16:36
Оценка: :)
Здравствуйте, pilgrim_, Вы писали:

_>Установить мин. кол-во потоков в пуле в 1000 (ThreadPool.SetMinThreads). Это не бесплатно ессн, но если очень надо .


Эх, жаль что вы мой козырь раскрыли. Думал может кто-то что-то нормальное предложит, но похоже другого варианта просто нет
Re[5]: [Этюд] - синхронный vs асинхронный
От: alexander_r  
Дата: 01.10.21 11:52
Оценка: +1
Здравствуйте, Shmj, Вы писали:
S>А чем плохо пул из 1 млн. потоков

Caution

By default, the minimum number of threads is set to the number of processors on a system. You can use the SetMinThreads method to increase the minimum number of threads. However, unnecessarily increasing these values can cause performance problems. If too many tasks start at the same time, all of them might appear to be slow. In most cases, the thread pool will perform better with its own algorithm for allocating threads. Reducing the minimum to less than the number of processors can also hurt performance.


https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.setminthreads?view=netframework-4.7.2
Re: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 29.09.21 07:06
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Вопрос: как сделать, чтобы асинхронный метод отрабатывал так же быстро?


А почему AsyncMethod(iCopy).Wait();
а не await AsyncMethod(iCopy)
И зачем в асинхронном еще и отдельный ask.Factory.StartNew
https://docs.microsoft.com/ru-ru/dotnet/csharp/language-reference/proposals/csharp-7.1/async-main
и солнце б утром не вставало, когда бы не было меня
Отредактировано 29.09.2021 9:19 Serginio1 . Предыдущая версия .
Re: [Этюд] - синхронный vs асинхронный
От: BlackEric http://black-eric.lj.ru
Дата: 29.09.21 09:07
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Вопрос: как сделать, чтобы асинхронный метод отрабатывал так же быстро?


Wait() блокирует поток исполнения. Нужно как минимум переписать через await, а потом уже смотреть что получается по скорости ища профайлером узкое место.
https://github.com/BlackEric001
Re[2]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 09:17
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>А почему AsyncMethod(iCopy).Wait();

S>а не await AsyncMethod(iCopy)
S>https://docs.microsoft.com/ru-ru/dotnet/csharp/language-reference/proposals/csharp-7.1/async-main

Без разницы — это проблему не решит.

Переписал без него — разницы нет.
Отредактировано 29.09.2021 9:26 Shmj . Предыдущая версия .
Re[2]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 09:18
Оценка:
Здравствуйте, BlackEric, Вы писали:

BE>Wait() блокирует поток исполнения. Нужно как минимум переписать через await, а потом уже смотреть что получается по скорости ища профайлером узкое место.


Это проблему не решит абсолютно. Переписал без него, чтобы не резало глаз.
Отредактировано 29.09.2021 9:26 Shmj . Предыдущая версия .
Re[4]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 09:28
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> И зачем там отдельный Task.Factory.StartNew и тем более без LongRunning


Где Task.Factory.StartNew без LongRunning?

Только один раз и только с LongRunning.

S>То есть ты уже пробовал?

S> Там LongRunning запускает отдельные потоки для каждой задачи. 1000 потоков при переключении могут и тормозить.

Попробуйте убрать LongRunning — без него и первый вариант начнет тормозить.
Отредактировано 29.09.2021 9:28 Shmj . Предыдущая версия .
Re[5]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 29.09.21 10:27
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Попробуйте убрать LongRunning — без него и первый вариант начнет тормозить.


То есть такой код тоже тормозит?

static async Task Main(string[] args)
        {
            for (int i = 0; i < 1000; i++)
            {
                int iCopy = i;

              await AsyncMethod(iCopy);

            }
            Console.ReadKey();
        }

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


static async Task Main(string[] args)
        {
   Task[] tasks=new Task[1000];
            for (int i = 0; i < 1000; i++)
            {
                int iCopy = i;

              tasks[i]=AsyncMethod(iCopy);

            }
 await Task.WhenAll(tasks);
            Console.ReadKey();
        }
и солнце б утром не вставало, когда бы не было меня
Отредактировано 29.09.2021 10:38 Serginio1 . Предыдущая версия . Еще …
Отредактировано 29.09.2021 10:33 Serginio1 . Предыдущая версия .
Отредактировано 29.09.2021 10:32 Serginio1 . Предыдущая версия .
Re[6]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 10:36
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>
S>static async Task Main(string[] args)
S>        {
S>   Task[] tasks=new Task[1000];
S>            for (int i = 0; i < 1000; i++)
S>            {
S>                int iCopy = i;

S>              tasks[i]=AsyncMethod(iCopy);

S>            }
S> await Task.WhenAll(tasks);
S>            Console.ReadKey();
S>        }
S>


Попробуйте запустить код перед тем как публиковать — этот код выполняется несколько минут, а 1 вариант — 2 секунды.
Re[7]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 29.09.21 10:42
Оценка:
Здравствуйте, Shmj, Вы писали:

Ну Thread.Sleep(1000); в сихронном варианте переключает потоки
И проще 1000 потоков запустить. А вот для пула потоков это хреново, так как тогда надо и пул потоков расширять.
Поэтому и нехорошо совмещать методы с потоками и задачами.
Ты внутри задачи которая лонг вызываешь васинхронный код который внутри в итоге и вызывает Thread.Sleep(1000)
и солнце б утром не вставало, когда бы не было меня
Отредактировано 29.09.2021 10:44 Serginio1 . Предыдущая версия .
Re[8]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 10:50
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Поэтому и нехорошо совмещать методы с потоками и задачами.


Может и не хорошо, но из асинхронных методов приходится вызывать сторонние синхронные, в которых есть аналоги Thread.Sleep(1000) в том или ином варианте.

Мы же не сможем все методы переписать под себя, все сделать асинхронными.

Так же из этого же метода приходится вызывать синхронные.

Что же делать?

S> Ты внутри задачи которая лонг вызываешь васинхронный код который внутри в итоге и вызывает Thread.Sleep(1000)


Предлагайте решение.
Re: [Этюд] - синхронный vs асинхронный
От: alexander_r  
Дата: 29.09.21 11:22
Оценка:
Здравствуйте, Shmj, Вы писали:
S>Итак, если запустить код — то увидим, что синхронный вариант отработает за 1-2 секунды а асинхронный — около 1 минуты (примерно, не ждал до конца).
А что вы замеряете время исполнения цикла от for (int i = 0; i < 1000; i++) до Console.ReadKey();
или итоговое время выполнения всех задач т.е когда последняя задача завершится ??
Re[10]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 11:50
Оценка:
Здравствуйте, Serginio1, Вы писали:

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


Так там в одном методе вызов и синхронных и асинхронных внешних методов — вот в чем фишка.

S>Асинхронный код не поможет, а только засрет пул потоков. Или выделяй отдельно долгий синхронный метод в Task c LongRunning


А если там много разных методов синхронных, не явно какие из них долгие? Все оборачивать предлагаете?
Re[2]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 11:51
Оценка:
Здравствуйте, alexander_r, Вы писали:

_>А что вы замеряете время исполнения цикла от for (int i = 0; i < 1000; i++) до Console.ReadKey();

_>или итоговое время выполнения всех задач т.е когда последняя задача завершится ??

Конечно итоговое исполнение всех задач.
Re[11]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 29.09.21 12:10
Оценка:
Здравствуйте, Shmj, Вы писали:

S>>Асинхронный код не поможет, а только засрет пул потоков. Или выделяй отдельно долгий синхронный метод в Task c LongRunning


S>А если там много разных методов синхронных, не явно какие из них долгие? Все оборачивать предлагаете?

Есть профайлер. И таких методов немного
и солнце б утром не вставало, когда бы не было меня
Re[12]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 12:13
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>А если там много разных методов синхронных, не явно какие из них долгие? Все оборачивать предлагаете?

S> Есть профайлер. И таких методов немного

Вы можете заранее не знать реализацию метода — работать через контракты, конкретная реализация выбирается в рантайме в зависимости от данных.

Есть способ сделать проще — не оборачивая каждый метод в отдельности и не заморачиваться с профайлером.
Re[13]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 29.09.21 12:16
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>>>А если там много разных методов синхронных, не явно какие из них долгие? Все оборачивать предлагаете?

S>> Есть профайлер. И таких методов немного

S>Вы можете заранее не знать реализацию метода — работать через контракты, конкретная реализация выбирается в рантайме в зависимости от данных.


S>Есть способ сделать проще — не оборачивая каждый метод в отдельности и не заморачиваться с профайлером.

Так я тебе и написал. С синхронным кодом работай синхронно. Смешивать ненужно.
Если же хочешь оптимизировать то выделяй весь синхронный код в LongRunning
и солнце б утром не вставало, когда бы не было меня
Re[14]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 12:20
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> Так я тебе и написал. С синхронным кодом работай синхронно. Смешивать ненужно.


Смешивать или нет — это зависит от сторонних библиотек. Часть библиотек имеет асинхронную реализацию, часть синхронную. И все это нужно вызвать в одном методе.

S>Если же хочешь оптимизировать то выделяй весь синхронный код в LongRunning


Получается криво — внутри метода много однотипных оберток. Можно сделать все проще.
Re[15]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 29.09.21 12:22
Оценка:
Здравствуйте, Shmj, Вы писали:
S>Получается криво — внутри метода много однотипных оберток. Можно сделать все проще.
Угу нужно пользоваться нормальными библиотеками. Которые не совмещают работу с потоками и задачами
и солнце б утром не вставало, когда бы не было меня
Отредактировано 29.09.2021 12:25 Serginio1 . Предыдущая версия .
Re[16]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 12:28
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>Получается криво — внутри метода много однотипных оберток. Можно сделать все проще.

S>Угу нужно пользоваться нормальными библиотеками. Которые не совмещают работу с потоками и задачами

Это две разные библиотеки. Она через потоки, другая через задачи. И вызывать их нужно в одном методе несколько раз. Оборачивать каждый вызов обычного метода в Task.Factory.StartNew — не красиво.
Re[17]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 29.09.21 12:30
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>>>Получается криво — внутри метода много однотипных оберток. Можно сделать все проще.

S>>Угу нужно пользоваться нормальными библиотеками. Которые не совмещают работу с потоками и задачами

S>Это две разные библиотеки. Она через потоки, другая через задачи. И вызывать их нужно в одном методе несколько раз. Оборачивать каждый вызов обычного метода в Task.Factory.StartNew — не красиво.

Сделай класс наследник и добавь асинхронные методы через LongRunning или через SG
и солнце б утром не вставало, когда бы не было меня
Отредактировано 29.09.2021 12:31 Serginio1 . Предыдущая версия .
Re[18]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 12:36
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Сделай класс наследник и добавь асинхронные методы через LongRunning или через SG


Т.е. вы таки весь мир хотите переделать на async? Для каждой библиотеки делать со-библиотеку наследника/обертку с асинхронной версией?

А нельзя ли без этой лишней работы?
Re[19]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 29.09.21 12:42
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>>Сделай класс наследник и добавь асинхронные методы через LongRunning или через SG


S>Т.е. вы таки весь мир хотите переделать на async? Для каждой библиотеки делать со-библиотеку наследника/обертку с асинхронной версией?


S>А нельзя ли без этой лишней работы?

Я предлагаю использовать нормальные асинхронные библиотеки, а не скрещивать работу с потоками и задачами.
Да для работы с асинхронным кодом должны быть и асинхронные библиотеки. На Windows Phone изначально не было методов с ожиданием выполнения другого потока или ожидание IO.
Если метод долгий то его нужно выделять в LongRunning
и солнце б утром не вставало, когда бы не было меня
Re[20]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 13:06
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> Я предлагаю использовать нормальные асинхронные библиотеки, а не скрещивать работу с потоками и задачами.


Не все библиотеки имеют асинхронную версию методов — это просто факт, который мы изменить не можем. Неужели единственный вариант — добавить обертку:

await Task.Factory.StartNew(() =>
                {
                    // ...
                }, TaskCreationOptions.LongRunning);



для каждого метода?

S>Если метод долгий то его нужно выделять в LongRunning


Почему нельзя 1 раз указать этот LongRunning?
Re[21]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 29.09.21 13:17
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Почему нельзя 1 раз указать этот LongRunning?

Можешь. Просто если метод быстрый (который может и проинлайниться), то зачем запускать отдельный поток?
Смысл асинхронного кода как раз в том, что есть немного синхронного кода, но большая часть кода выполняется в другом процессе (базы данных, HTTP сервера,TCP)
либо IO. Длинные методы как правило распараллеливаются и можно отдельно выделять LongRunning но таких методов немного
и солнце б утром не вставало, когда бы не было меня
Отредактировано 29.09.2021 13:19 Serginio1 . Предыдущая версия .
Re[22]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 13:23
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>Почему нельзя 1 раз указать этот LongRunning?

S> Можешь.

Каким образом?
Re[4]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 14:06
Оценка:
Здравствуйте, paradok, Вы писали:

P>да, не ожидал, действительно тормоз, ... получается async какие-то ущербные?

P>И что делать?

Это мы тут и обсуждаем

Пока ответ не очевиден.
Re[23]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 29.09.21 14:11
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>>>Почему нельзя 1 раз указать этот LongRunning?

S>> Можешь.

S>Каким образом?

Заверни весь синхронный код в Task с LongRunning
и солнце б утром не вставало, когда бы не было меня
Re[24]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 14:13
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>Каким образом?

S> Заверни весь синхронный код в Task с LongRunning

Если вызовов синхронных методов много (чередуются с async) и как долго они исполняются — не определено (зависит от данных) — предлагаете заворачивать каждый в отдельности? Как завернуть 1 раз для всех — вот в чем вопрос.
Отредактировано 29.09.2021 14:14 Shmj . Предыдущая версия .
Re[26]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 29.09.21 15:29
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> Ждать развития PGO, аналогом HotSpot

S>https://github.com/dotnet/runtime/blob/main/docs/design/features/DynamicPgo.md

Есть вариант как решить сегодня. Думайте.
Re: [Этюд] - синхронный vs асинхронный
От: Ночной Смотрящий Россия  
Дата: 30.09.21 06:48
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Что-то давно этюдов не было. Не знаю тянет ли это на этюд, но попробую.


У тебя какая то фигня написана. Ты ни там ни там не ждешь завершения задач и непонятно что измеряешь. Лень экспериментировать, но разница, скорее всего, связана с настройкой IsBackground потоков.
Тебе надо что то вроде:
await Enumerable
    .Range(1000)
    .Select(i => Task.Factory.StartNew(...))
    .WhenAll();
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 30.09.21 06:55
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

Там проблема в Thread.Sleep(1000);
http://rsdn.org/forum/dotnet/8102654.1
Автор: Serginio1
Дата: 29.09.21
и солнце б утром не вставало, когда бы не было меня
Re[2]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 30.09.21 07:33
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>У тебя какая то фигня написана. Ты ни там ни там не ждешь завершения задач и непонятно что измеряешь. Лень экспериментировать, но разница, скорее всего, связана с настройкой IsBackground потоков.


Там по завершении задачи на экран выводится номер задачи. Синхронная версия отрабатывает 1-2 сек., асинхронная 1-2 мин.

Проверь — будешь удивлен.
Re[3]: [Этюд] - синхронный vs асинхронный
От: alexander_r  
Дата: 30.09.21 09:27
Оценка:
Здравствуйте, Shmj, Вы писали:

S>...Синхронная версия отрабатывает 1-2 сек., асинхронная 1-2 мин.

а как вы время замеряете, покажите весь код??
Re[4]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 30.09.21 10:02
Оценка:
Здравствуйте, alexander_r, Вы писали:

S>>...Синхронная версия отрабатывает 1-2 сек., асинхронная 1-2 мин.

_>а как вы время замеряете, покажите весь код??

Там и так все понятно, разница на порядки. Ну могу дописать ожидание завершения всех задач, но это ничего не изменит.
Re[5]: [Этюд] - синхронный vs асинхронный
От: paradok  
Дата: 30.09.21 10:08
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, alexander_r, Вы писали:


S>>>...Синхронная версия отрабатывает 1-2 сек., асинхронная 1-2 мин.

_>>а как вы время замеряете, покажите весь код??

S>Там и так все понятно, разница на порядки. Ну могу дописать ожидание завершения всех задач, но это ничего не изменит.


да, сделай ! там еще можно будет посмотреть зависимость от задержки, при 10 сек вообще кранты наступают системе.
Re[6]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 30.09.21 10:31
Оценка:
Здравствуйте, paradok, Вы писали:

S>>Там и так все понятно, разница на порядки. Ну могу дописать ожидание завершения всех задач, но это ничего не изменит.

P>да, сделай ! там еще можно будет посмотреть зависимость от задержки, при 10 сек вообще кранты наступают системе.

Добавил в стартовом сообщении.
Re: [Этюд] - синхронный vs асинхронный
От: Teolog  
Дата: 30.09.21 10:50
Оценка:
S>Вопрос: как сделать, чтобы асинхронный метод отрабатывал так же быстро?
Подозреваю что суть проблемы в присутсвие синхронного ожидания Thread.Sleep(1000) после await.
Если я правильно понял ситуацию, то после await Task.Delay(1); оно уже выполняеться не на свеже-запущенном longRunning потоке
а на первом попавшемся из пула. Запущенный уже к этому моменту благополучно помер.
Соотвественно код выполняеться за время 1 *1000 / (размер пулла потоков)
Решение — обернуть синхронное ожидание в await Task.Factory.StartNew(longRunning), а из первоначального запуска задач этот параметр убрать.
Тогда, все что можно сделать на пуле-будет сделано на пуле, остальное на 1000 фоновых потоков.
Лучше оно от этого, по-сравнению с синхронным вариантом работать не будет, но будет хотя-бы так же криво. а не сильно хуже.
Ну еще можно побаловться с контекстом синхронизации, что замаскирет проблему и код станет таким же кривым и бажным как UI Windows
Чтобы работало нормально- надо лезть в библиотеку и переделывать ту синхронную функцию которую у вас символизирует Thread.Sleep(1000)
Re[2]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 30.09.21 11:02
Оценка:
Здравствуйте, Teolog, Вы писали:

T>Ну еще можно побаловться с контекстом синхронизации, что замаскирет проблему и код станет таким же кривым и бажным как UI Windows


Вот это интересно посмотреть...

T>Чтобы работало нормально- надо лезть в библиотеку и переделывать ту синхронную функцию которую у вас символизирует Thread.Sleep(1000)


Вы что весь мир будете переделывать под async? Знаете сколько библиотек, которые игнорят Task'и?
Re[3]: [Этюд] - синхронный vs асинхронный
От: Teolog  
Дата: 30.09.21 11:12
Оценка:
S>Вы что весь мир будете переделывать под async? Знаете сколько библиотек, которые игнорят Task'и?
Кто, я? Да чур меня, делать мне больше нечего.
Суть async/await в использовании кооперативной многозадачности для уменьшения количества ждущих потоков.
Проблема та-же что и во времена windows 3.11 — при плохом поведении любого кода в дальнем углу, встает колом всё.
В общем виде, проблема не решаеться никак,но в пределах своего кода и надежных библиотек требуемый результат достижим.
Поэтому этот самый async постепенно расползаеться везде где возможно ожидание данных.
S>Знаете сколько библиотек, которые игнорят Task'и?
Вероятно много, однако любая библиотека без async работающая со вводом-выводом и периферийными устройствами строем идет нафиг, сразу как находится замена.
Re[6]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 30.09.21 11:27
Оценка:
Здравствуйте, alexander_r, Вы писали:

_>не знаю откуда у вас там разица на порядок

_>у меня ваш синхронный метод и тот что переделал Serginio1 выполняется за одинаковое время ~7.5сек

Serginio1 предлагает добавлять обертку для каждого вызова синхронного метода, который мы можем подозревать в длительном исполнении — а это уродство.
Re[7]: [Этюд] - синхронный vs асинхронный
От: alexander_r  
Дата: 30.09.21 11:41
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Serginio1 предлагает добавлять обертку для каждого вызова синхронного метода, который мы можем подозревать в длительном исполнении — а это уродство.


т.е проблемы с производительностью нет, проблема в уродстве??
Re[9]: [Этюд] - синхронный vs асинхронный
От: alexander_r  
Дата: 30.09.21 12:21
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Выбор из двух: или тормоза или уродство.


не знаю почему уродство, вполне рабочее решение
Re: [Этюд] - синхронный vs асинхронный
От: Danchik Украина  
Дата: 30.09.21 14:22
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Что-то давно этюдов не было. Не знаю тянет ли это на этюд, но попробую.


[Skip]

Скажите, почему эмуляция Асинхронного вызова делается через Thread.Sleep()?
Или поправьте на
await Task.Delay(1000)

или поправьте коментарий что, вы делаете эмуляцию Синхронного вызова.
Re[3]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 30.09.21 15:01
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>А использовать он хочет его в асинхронном коде. И говорит, что есть простое решение.

S>А завертывание долгого синхронного кода

S>
S> await Task.Factory.StartNew(() =>
S>            {
S>                Thread.Sleep(1000);
S>            }, TaskCreationOptions.LongRunning);
S>


S>Не красиво


Ага. Представьте 5 вызовов в методе (чередуются с синхронным) и 5 ваших гармошек с Task.Factory.StartNew...

На каждый вызов вы создаете по отдельному потому. А в синхронной версии всего 1 поток на метод. Тут не просто не красиво — тут еще и не оптимально.
Отредактировано 30.09.2021 15:02 Shmj . Предыдущая версия .
Re[4]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 30.09.21 15:07
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Ага. Представьте 5 вызовов в методе (чередуются с синхронным) и 5 ваших гармошек с Task.Factory.StartNew...


S>На каждый вызов вы создаете по отдельному потому. А в синхронной версии всего 1 поток на метод. Тут не просто не красиво — тут еще и не оптимально.


Еще раз разработчик библиотеки не должен смешивать работу с задачами и потоками! Это разные парадигмы и есть асинхронные аналоги.
Если жевсе же ты решишл использовать, то ССЗС и тогда нужно профилировать код.
Ибо есть короткий и долгий код. Вот для долгого то кода и нужен отдельныая задача с LongRunning, что бы не останавливал поток из пула.
А все остальные используй как синхронный.
Мне интересно какое решение у тебя без использования профайлера
и солнце б утром не вставало, когда бы не было меня
Re[5]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 30.09.21 15:10
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Мне интересно какое решение у тебя без использования профайлера


Подождем еще — может кто-то решит этюд.
Re[3]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 01.10.21 08:45
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, pilgrim_, Вы писали:


_>>Установить мин. кол-во потоков в пуле в 1000 (ThreadPool.SetMinThreads). Это не бесплатно ессн, но если очень надо .


S>Эх, жаль что вы мой козырь раскрыли. Думал может кто-то что-то нормальное предложит, но похоже другого варианта просто нет

Ну да. Пул из 1000 потоков это коронное решение?
По моему мое решение с профайлером намного оптимальнее!
и солнце б утром не вставало, когда бы не было меня
Re[5]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 01.10.21 09:25
Оценка:
Здравствуйте, Shmj, Вы писали:

S>А чем плохо пул из 1 млн. потоков? Они же не будут создаваться без необходимости?

Почему не будут. Когда у тебя стоит ограничение, то лишние задачи встают в очередь и новых потоков не создается,
а когда нет и много одновременных задач не встают в очередь и есть затраты на создание потока и на переключение между потоками
http://rsdn.org/forum/philosophy/8038767.1
Автор: Serginio1
Дата: 28.06.21
и солнце б утром не вставало, когда бы не было меня
Отредактировано 01.10.2021 12:29 Serginio1 . Предыдущая версия . Еще …
Отредактировано 01.10.2021 9:27 Serginio1 . Предыдущая версия .
Re[5]: [Этюд] - синхронный vs асинхронный
От: Danchik Украина  
Дата: 01.10.21 14:04
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>> Ну да. Пул из 1000 потоков это коронное решение?

S>>По моему мое решение с профайлером намного оптимальнее!

S>А чем плохо пул из 1 млн. потоков? Они же не будут создаваться без необходимости?


Один поток — 4MB на стек для x64. Множим на миллион и уходим в своп. Или точнее в никуда, 4 терабайта это серьезно
Re[6]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 01.10.21 14:42
Оценка:
Здравствуйте, Danchik, Вы писали:

D>Один поток — 4MB на стек для x64. Множим на миллион и уходим в своп. Или точнее в никуда, 4 терабайта это серьезно


Создал 10 тыс. потоков в ожидании, заняло 270 Мб. памяти. Получается примерно по 27 Кб на поток. Так что не так страшен черт...

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

Если в пуле потоков установить 1 млн. — он их не создает сразу.
Re[6]: [Этюд] - синхронный vs асинхронный
От: Sharov Россия  
Дата: 01.10.21 14:52
Оценка:
Здравствуйте, Danchik, Вы писали:


S>>А чем плохо пул из 1 млн. потоков? Они же не будут создаваться без необходимости?

D>Один поток — 4MB на стек для x64.

Вроде бы 1Мб всегда был? Или в core что-то поменялось?
Кодом людям нужно помогать!
Re[7]: [Этюд] - синхронный vs асинхронный
От: Sharov Россия  
Дата: 01.10.21 14:58
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Создал 10 тыс. потоков в ожидании, заняло 270 Мб. памяти. Получается примерно по 27 Кб на поток. Так что не так страшен черт...


А можно скрин соотв. фото из Process Exploer'а, ибо 270Мб это физически потребленная память,
а виртуально там 10^4 * 10^6 байт (10Гб вроде?).
Кодом людям нужно помогать!
Re[8]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 01.10.21 15:02
Оценка:
Здравствуйте, Sharov, Вы писали:

S>А можно скрин соотв. фото из Process Exploer'а, ибо 270Мб это физически потребленная память,

S>а виртуально там 10^4 * 10^6 байт (10Гб вроде?).

Запустите код и сообщите что увидели, вам это тоже нужно знать:

  private static List<Thread> _threads = new List<Thread>();

        static async Task Main(string[] args)
        {
            ThreadPool.SetMinThreads(1000000, 1);


            for (int i = 0; i < 10000; i++)
            {
                var t = new Thread(() =>
                    {
                        Thread.Sleep(100000);
                    })
                    {IsBackground = true};

                t.Start();

                _threads.Add(t);
            }

            Console.WriteLine("Done");
            Console.ReadKey();
        }
Re[9]: [Этюд] - синхронный vs асинхронный
От: Sharov Россия  
Дата: 01.10.21 15:49
Оценка:
Здравствуйте, Shmj, Вы писали:

S>>А можно скрин соотв. фото из Process Exploer'а, ибо 270Мб это физически потребленная память,

S>>а виртуально там 10^4 * 10^6 байт (10Гб вроде?).
S>Запустите код и сообщите что увидели, вам это тоже нужно знать:

Ну и, кучу виртуальной памяти зарезервировано.
Кодом людям нужно помогать!
Re[10]: [Этюд] - синхронный vs асинхронный
От: Shmj Ниоткуда  
Дата: 01.10.21 17:00
Оценка:
Здравствуйте, Sharov, Вы писали:

Ну так что? Сколько реально потребили 10 тыс. потоков? Вряд ли у вас в приложении столько будет, верно?

S>Ну и, кучу виртуальной памяти зарезервировано.


Что жалко что ли на 64 битке она практически бесконечна.
Отредактировано 01.10.2021 17:01 Shmj . Предыдущая версия .
Re[11]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 01.10.21 17:46
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Что жалко что ли на 64 битке она практически бесконечна.

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

Кроме того, что очень важно, при переключении контекста происходят следующие программно-незаметные аппаратные действия, влияющие на производительность:

Происходит очистка конвейера команд и данных процессора
Очищается TLB, отвечающий за страничное отображение линейных адресов на физические.
Кроме того, следует учесть следующие факты, влияющие на состояние системы:

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

Ну и если задачи короткие то они могут быть соизмеремы с временем переключения контекста
и солнце б утром не вставало, когда бы не было меня
Отредактировано 01.10.2021 17:52 Serginio1 . Предыдущая версия .
Re[11]: [Этюд] - синхронный vs асинхронный
От: Sharov Россия  
Дата: 01.10.21 19:24
Оценка:
Здравствуйте, Shmj, Вы писали:

S>>Ну и, кучу виртуальной памяти зарезервировано.

S>Что жалко что ли на 64 битке она практически бесконечна.

Да, так как в какой-то момент это в io уткнется.
Кодом людям нужно помогать!
Re[6]: [Этюд] - синхронный vs асинхронный
От: Teolog  
Дата: 01.10.21 19:36
Оценка:
D>Один поток — 4MB на стек для x64. Множим на миллион и уходим в своп. Или точнее в никуда, 4 терабайта это серьезно
Оно почти не кушает памяти само по себе, выделение страниц идет по требованию, а адресного пространства которое действительно выделяется -вагон.
Re[13]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 01.10.21 22:50
Оценка:
Здравствуйте, Sharov, Вы писали:

S>По ссылке не ходил, но речь идет о процессах, а не о потоках -- потоки как раз придумали, чтобы не сбрасывать

S>кэш и т.п. Т.е. переключение процессов дорого, а потоков в процессе -- нет.
Согласен, но процессов то может быть и не один. И так гонок за процессорное время будет больше
и солнце б утром не вставало, когда бы не было меня
Re[14]: [Этюд] - синхронный vs асинхронный
От: Sharov Россия  
Дата: 04.10.21 10:52
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>По ссылке не ходил, но речь идет о процессах, а не о потоках -- потоки как раз придумали, чтобы не сбрасывать

S>>кэш и т.п. Т.е. переключение процессов дорого, а потоков в процессе -- нет.
S>Согласен, но процессов то может быть и не один. И так гонок за процессорное время будет больше

Речь идет о потоках в процессе. Остальное не интересно.
Кодом людям нужно помогать!
Re[15]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.10.21 10:17
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>>>По ссылке не ходил, но речь идет о процессах, а не о потоках -- потоки как раз придумали, чтобы не сбрасывать

S>>>кэш и т.п. Т.е. переключение процессов дорого, а потоков в процессе -- нет.
S>>Согласен, но процессов то может быть и не один. И так гонок за процессорное время будет больше

S>Речь идет о потоках в процессе. Остальное не интересно.

Да но, переключаться то приходится и на другие потоки процессов. Суть то в том, что хотят выделять пул потоков без ограничения.
А вот тут то как раз и возникают проблемы при переключении с на потоки с других процессов, гонки за потоки
и солнце б утром не вставало, когда бы не было меня
Отредактировано 16.10.2021 10:33 Serginio1 . Предыдущая версия .
Re[16]: [Этюд] - синхронный vs асинхронный
От: Sharov Россия  
Дата: 16.10.21 10:35
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>Речь идет о потоках в процессе. Остальное не интересно.

S>Да но, переключаться то приходится и на другие потоки процессов. Суть то в том, что хотят выделять пул потоков без ограничения.
S>А вот тут то как раз и возникают проблемы при переключении с на потоки с других процессов, гонки за потоки

Переключение между потоками дешево по сравнению с процессами.
Кодом людям нужно помогать!
Re[17]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.10.21 11:14
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>>>Речь идет о потоках в процессе. Остальное не интересно.

S>>Да но, переключаться то приходится и на другие потоки процессов. Суть то в том, что хотят выделять пул потоков без ограничения.
S>>А вот тут то как раз и возникают проблемы при переключении с на потоки с других процессов, гонки за потоки

S>Переключение между потоками дешево по сравнению с процессами.

Еще раз, для других процессов разве не нужны ядра для переключения на свои потоки?
И разве не ббудет гонок за потками если бездумно выделять огромное количество в пуле потоков?
и солнце б утром не вставало, когда бы не было меня
Отредактировано 16.10.2021 11:15 Serginio1 . Предыдущая версия .
Re[18]: [Этюд] - синхронный vs асинхронный
От: Sharov Россия  
Дата: 16.10.21 13:29
Оценка:
Здравствуйте, Serginio1, Вы писали:


S>>Переключение между потоками дешево по сравнению с процессами.

S>Еще раз, для других процессов разве не нужны ядра для переключения на свои потоки?

Нужны и что?

S>И разве не ббудет гонок за потками если бездумно выделять огромное количество в пуле потоков?


Что такое гонка за потоками? Если потоков много, гонки должно быть меньше. Разве нет?
Кодом людям нужно помогать!
Re[19]: [Этюд] - синхронный vs асинхронный
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.10.21 15:01
Оценка:
Здравствуйте, Sharov, Вы писали:
S>>И разве не ббудет гонок за потками если бездумно выделять огромное количество в пуле потоков?

S>Что такое гонка за потоками? Если потоков много, гонки должно быть меньше. Разве нет?

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

>>По ссылке не ходил, но речь идет о процессах, а не о потоках -- потоки как раз придумали, чтобы не сбрасывать

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

То есть два разных потока работают с разными данными. Это могут быть огромные массивы данных.
Там на время работы потока то данные кэша меняются
Как эти данные могут держаться в кэше?
и солнце б утром не вставало, когда бы не было меня
Отредактировано 16.10.2021 15:09 Serginio1 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.