C # Асинхронный с задачей медленнее, чем синхронный - PullRequest
0 голосов
/ 18 сентября 2018

Знаете ли вы, почему метод синхронизации Фибоначчи быстрее, чем async / await, и это быстрее, чем асинхронная задача?

Я использовал асинхронность в каждом методе проекта, так что, главное, это такой плохой подход ...

Код:

        static int FibonacciSync(int number)
        {
            if (number == 0) { return 0; }
            else if (number == 1) { return 1; }
            else
            {
                var t1 = FibonacciSync(number - 1);
                var t2 = FibonacciSync(number - 2);
                return t1 + t2;
            }
        }

        async static Task<int> FibonacciAwait(int number)
        {
            if (number == 0) 
            { return 0; }
            else if (number == 1) 
            { return 1; }
            else
            {
                var task1 = FibonacciAwait(number - 1);
                var task2 = FibonacciAwait(number - 2);
                return (await task1) + (await task2);
            }
        }

        static Task<int> FibonacciAsync(int number)
        {
            if (number == 0) 
            { return Task.FromResult(0); }
            else if (number == 1) 
            { return Task.FromResult(1); }
            else
            {
                return FibonacciAsync(number - 1).ContinueWith(task1 =>
                {
                    return FibonacciAsync(number - 2).ContinueWith(task2 =>
                    {
                        return task1.Result + task2.Result;
                    });
                }).Unwrap();
            }
        }

Результат:

  • Синхронизация: 00: 00: 00.0121900
  • Ожидание: 00: 00: 00.2118170
  • Async: 00: 00: 02.6211660

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Знаете ли вы, почему метод синхронизации Фибоначчи быстрее, чем асинхронное / ожидание, и быстрее, чем асинхронная задача?

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

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

Задержка - это разрыв во времени между тем, когда вы запрашиваете вычисление или побочный эффект, и когдарасчет или побочный эффект завершен .

Например, предположим, что вы вычисляете что-то, что чрезвычайно вычислительно дорого .Например, вы вычисляете действительно сложную графику, и на ее вычисление уйдет более 30 миллисекунд, даже если вы посвятите ей целое ядро.Вы не хотите, чтобы ваш пользовательский интерфейс зависал во время выполнения вычислений, поэтому вы можете поместить вычисления в другой поток, выделить ЦП этому потоку и дождаться результата. Ожидание означает «иди и найди больше работы, пока я жду завершения операции с высокой задержкой» .

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

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

Используйте асинхронность только при выполнении операции с большой задержкой .Async повышает производительность, поскольку освобождает поток для продолжения работы, пока он ожидает появления результата с высокой задержкой.Если нет результата с высокой задержкой, то async просто все замедлит.

0 голосов
/ 18 сентября 2018

хорошее эмпирическое правило: используйте асинхронные вызовы только для функций, которые используют внешний ресурс: файловую систему, базу данных, вызовы http, ...

, когда вы выполняете в памяти такие вещи, как вычисление Фибоначчи, выполняйтепри синхронизации, затраты на создание отдельного потока / контекста для вычислений в памяти слишком велики

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...