我有一个简单的性能测试,间接调用WriteAsync
很多次。只要实现WriteAsync
,它就会合理地执行,如下所示。但是,当我将WriteByte
内联到WriteAsync
时,性能会下降约7倍。
(要明确:我所做的唯一更改是将WriteByte
调用的语句替换为WriteByte
的正文。)
有人可以解释为什么会这样吗?我已经看过使用Reflector生成的代码的差异,但没有任何东西让我感到如此完全不同,因为它可以解释巨大的性能。
public sealed override async Task WriteAsync(
byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
var writeBuffer = this.WriteBuffer;
var pastEnd = offset + count;
while ((offset < pastEnd) && ((writeBuffer.Count < writeBuffer.Capacity) ||
await writeBuffer.FlushAsync(cancellationToken)))
{
offset = WriteByte(buffer, offset, writeBuffer);
}
this.TotalCount += count;
}
private int WriteByte(byte[] buffer, int offset, WriteBuffer writeBuffer)
{
var currentByte = buffer[offset];
if (this.previousWasEscapeByte)
{
this.previousWasEscapeByte = false;
this.crc = Crc.AddCrcCcitt(this.crc, currentByte);
currentByte = (byte)(currentByte ^ Frame.EscapeXor);
++offset;
}
else
{
if (currentByte < Frame.InvalidStart)
{
this.crc = Crc.AddCrcCcitt(this.crc, currentByte);
++offset;
}
else
{
currentByte = Frame.EscapeByte;
this.previousWasEscapeByte = true;
}
}
writeBuffer[writeBuffer.Count++] = currentByte;
return offset;
}
答案 0 :(得分:2)
async
方法重写为巨型状态机,与使用yield return
的方法非常相似。您所有的本地人都成为状态机类中的字段。编译器目前根本不会尝试对此进行优化,因此任何优化都取决于编码器。
现在正在读取和写入记忆的每个本地人都会愉快地坐在寄存器中。重构async
方法的同步代码 out 并进入同步方法是一种非常有效的性能优化 - 你只是反过来了!