Я пытался найти узкое место ввода-вывода в своем классе и неожиданно заметил, что sw.Write("m"); sw.Flush()
может быть на 20000 быстрее, чем await sw.WriteAsync("m"); Await sw.FlushAsync();
при записи 1000000 сообщений в файл. А случайно никто не знает почему? Могу поспорить, что конструктор StreamWriter
, принимающий String
, не параметризует поток для использования async
.
Приведенный ниже код можно запустить из интерактивного C#. Да, это не лучшее место для измерения скорости, но оно все равно покажет, в чем дело:
var sr = new StreamWriter("G:\\file.file");
var N = 1000;
var sw = new Stopwatch();
sw.Start();
for (var i = 0; i < N; ++i)
{
sr.Write("m"); // or await sr.WriteAsync("m");
sr.Flush(); // or await sr.FlushAsync("m");
}
sw.Stop();
Console.WriteLine("Completed " + N
+ " iterations in " + sw.ElapsedMilliseconds + " milliseconds.");
sr.Close();
Запущенный на моем домашнем ПК из C# Interactive, вывод
Выполнено 1000 итераций за 1 миллисекунду.
для синхронного кода и
Выполнено 1000 итераций за 43383 миллисекунды.
для асинхронного.
Обновление: Также я заметил, что программа тормозит внутри FlushAsync
. WriteAsync
работает почти с той же скоростью, что и синхронная версия.
Все комментарии приветствуются.
Обновление 2*. Как упомянул @Cory Nelson в комментариях к своему ответу, FileStream.FlushAsync
— это поддельный async
, реализованный с помощью Task.Factory.StartNew
, поэтому он не добавляет ничего полезного, кроме накладных расходов. При работе с короткими сообщениями накладные расходы становятся достаточно большими по сравнению с выполняемой работой, что замедляет выполнение.
Stream
вручную, но он все еще намного медленнее, чем синхронная версия. Нет, я не пишу строки из одного символа, а пишу короткие сообщения журнала. Кроме того, для меня не так важны накладные расходы памяти/GC, потому что другие конструкции с асинхронными операциями вызываются несколько миллионов раз в секунду, и все в порядке. 01.02.2017FlushAsync
.WriteAsync
работает примерно с той же скоростью, что и синхронная версия. 01.02.2017FlushAsync
наFileStream
, к сожалению, реализован с поддельной асинхронностью. Я ожидал, что он будет работать не очень хорошо. 01.02.2017