在这种特定的命令行工具中,我不会期望异步的好处,但是我也不会期望得到如此大的惩罚。
在我的机器上,反复运行后,对于46 MB的输入文件(Git-2.27.0-64-bit.exe),异步版本的运行速度始终慢7倍左右。
outputFile
/ Flush
之前放置FlushAsync
流也要花这么长时间(平均约16秒),但是对于同步调用和异步调用,两者之间没有区别。ConfigureAwait(false)
中,这种特定的功能似乎并没有多大区别(而且我确实没想到会如此)CopyTo
/ CopyToAsync
中的缓冲区大小似乎并没有缩小差距。示例异步结果:
\Base64\bin\Release\netcoreapp3.1>Base64.exe
WriteFile completed in 00:02:40.5583442
Flushing outputFile
Flush outputFile completed in 00:00:00.0010565
disposing outputFile
disposed outputFile in 00:00:15.7304240
disposing base64Stream
disposed base64Stream in 00:00:00.0029926
disposing inputFile
disposed inputFile in 00:00:00.0002473
disposing base64Transform
disposed base64Transform in 00:00:00.0020258
Total Elapsed: 00:02:56.3132804
示例同步结果:
\Base64\Base64\bin\Release\netcoreapp3.1>Base64.exe
WriteFile completed in 00:00:08.9381189
Flushing outputFile
Flush outputFile completed in 00:00:00.0016328
disposing outputFile
disposed outputFile in 00:00:16.5799980
disposing base64Stream
disposed base64Stream in 00:00:00.0046472
disposing inputFile
disposed inputFile in 00:00:00.0019350
disposing base64Transform
disposed base64Transform in 00:00:00.0014333
Total Elapsed: 00:00:25.5501378
异步测试
static async Task Main(string[] args)
{
var totalStopWatch = new Stopwatch();
totalStopWatch.Start();
var stopWatch = new Stopwatch();
stopWatch.Start();
using (var base64Transform = new ToBase64Transform())
{
await using (FileStream inputFile = new FileStream(@"Git-2.27.0-64-bit.exe", FileMode.Open, FileAccess.Read))
{
await using (CryptoStream base64Stream = new CryptoStream(inputFile, base64Transform, CryptoStreamMode.Read))
{
await using (FileStream outputFile = new FileStream($@"outfile{Guid.NewGuid()}.html", FileMode.CreateNew, FileAccess.Write))
{
await outputFile.WriteAsync(Encoding.UTF8.GetBytes(@"<!doctype html>
<html>
<head>
<title>base 64 encoding test</title>
</head>
<body>
<img alt=""Ok so not really an image."" src=""data:image/jpeg;base64,")).ConfigureAwait(false);
await base64Stream.CopyToAsync(outputFile, 8192).ConfigureAwait(false);
await outputFile.WriteAsync(Encoding.UTF8.GetBytes(@""" />
</body>
</html>
")).ConfigureAwait(false);
Console.WriteLine($"WriteFile completed in {stopWatch.Elapsed}");
stopWatch.Restart();
Console.WriteLine($"Flushing {nameof(outputFile)}");
await outputFile.FlushAsync().ConfigureAwait(false);
Console.WriteLine($"Flush {nameof(outputFile)} completed in {stopWatch.Elapsed}");
stopWatch.Restart();
Console.WriteLine($"disposing {nameof(outputFile)}");
}
Console.WriteLine($"disposed outputFile in {stopWatch.Elapsed}");
stopWatch.Restart();
Console.WriteLine($"disposing {nameof(base64Stream)}");
}
Console.WriteLine($"disposed base64Stream in {stopWatch.Elapsed}");
stopWatch.Restart();
Console.WriteLine($"disposing {nameof(inputFile)}");
}
Console.WriteLine($"disposed inputFile in {stopWatch.Elapsed}");
stopWatch.Restart();
Console.WriteLine($"disposing {nameof(base64Transform)}");
}
Console.WriteLine($"disposed base64Transform in {stopWatch.Elapsed}");
Console.WriteLine($"Total Elapsed: {totalStopWatch.Elapsed}");
}
同步测试
static void Main(string[] args)
{
var totalStopWatch = new Stopwatch();
totalStopWatch.Start();
var stopWatch = new Stopwatch();
stopWatch.Start();
using (var base64Transform = new ToBase64Transform())
{
using (FileStream inputFile = new FileStream(@"Git-2.27.0-64-bit.exe", FileMode.Open, FileAccess.Read))
{
using (CryptoStream base64Stream = new CryptoStream(inputFile, base64Transform, CryptoStreamMode.Read))
{
using (FileStream outputFile = new FileStream($@"outfile{Guid.NewGuid()}.html", FileMode.CreateNew, FileAccess.Write))
{
outputFile.Write(Encoding.UTF8.GetBytes(@"<!doctype html>
<html>
<head>
<title>base 64 encoding test</title>
</head>
<body>
<img alt=""Ok so not really an image."" src=""data:image/jpeg;base64,"));
base64Stream.CopyTo(outputFile, 8192);
outputFile.Write(Encoding.UTF8.GetBytes(@""" />
</body>
</html>
"));
Console.WriteLine($"WriteFile completed in {stopWatch.Elapsed}");
stopWatch.Restart();
Console.WriteLine($"Flushing {nameof(outputFile)}");
outputFile.Flush();
Console.WriteLine($"Flush {nameof(outputFile)} completed in {stopWatch.Elapsed}");
stopWatch.Restart();
Console.WriteLine($"disposing {nameof(outputFile)}");
}
Console.WriteLine($"disposed outputFile in {stopWatch.Elapsed}");
stopWatch.Restart();
Console.WriteLine($"disposing {nameof(base64Stream)}");
}
Console.WriteLine($"disposed base64Stream in {stopWatch.Elapsed}");
stopWatch.Restart();
Console.WriteLine($"disposing {nameof(inputFile)}");
}
Console.WriteLine($"disposed inputFile in {stopWatch.Elapsed}");
stopWatch.Restart();
Console.WriteLine($"disposing {nameof(base64Transform)}");
}
Console.WriteLine($"disposed base64Transform in {stopWatch.Elapsed}");
Console.WriteLine($"Total Elapsed: {totalStopWatch.Elapsed}");
}