0

我有一个简单的性能测试,间接调用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;
}
4

1 回答 1

1

async编译器将方法重写为巨大的状态机,与使用yield return. 您所有的本地人都成为状态机类中的字段。编译器目前根本不会尝试对此进行优化,因此任何优化都取决于编码器。

每个本来可以愉快地坐在寄存器中的本地人现在正在被读取和写入内存。将同步代码从方法中重构async到同步方法中是一种非常有效的性能优化——你只是在做相反的事情!

于 2012-12-14T21:25:01.010 回答