Почему компилятор C # не оптимизирует простые асинхронные / ожидающие методы - PullRequest
0 голосов
/ 25 сентября 2019

Рассмотрим следующие два метода C #.Несмотря на функциональную эквивалентность, первая из них, по-видимому, лучше работает, как это предусмотрено соответствующими инструкциями по IL.

Быстрее:

static Task<string> Proxy(string text)
{
  return Foo(text);
}

enter image description here

Медленнее:

static async Task<string> ProxyAsync(string text)
{
  return await Foo(text);
}

enter image description here

Из моего понимания компилятор под капотом заменяет awaitинструкции со сложным конечным автоматом.

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

Кроме того, каковы (не) преимущества выполнения таких оптимизаций вручную в коде C # (т.е. намеренное предпочтение более быстрой реализации по сравнению с более медленной).

1 Ответ

9 голосов
/ 25 сентября 2019

Почему компилятор C # не оптимизирует простые асинхронные / ожидающие методы

Поскольку каждая функция (включая оптимизацию) начинается с минус 100 баллов .Это особенно верно, если семантика различна, чем они являются в данном случае .

Разница невелика, но если вы определите Foo как:

Task Foo(string text)
{
  throw new NotImplementedException();
}

тогда поведение Proxy и ProxyAsync различно.Proxy будет передавать исключение непосредственно вызывающей стороне;ProxyAsync будет захватывать это исключение и помещать его в Task, возвращаемое из ProxyAsync.

У меня есть пост в блоге, в котором более подробно рассматриваются мысли, которые следует учитывать при отборе async иawait.

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