gpt4 book ai didi

c# - 如何防止 JIT 编译器优化此方法

转载 作者:行者123 更新时间:2023-11-30 14:02:50 33 4
gpt4 key购买 nike

我有一个如下所示的扩展方法:

//[MethodImpl(MethodImplOptions.NoOptimization)]
public static IEnumerable<char> TakeWhile(this BinaryReader reader, Func<int, bool> condition)
{
while (condition(reader.PeekChar()))
{
char c = reader.ReadChar();
yield return c;
}
}

我在使用 BinaryReader 解析文件时使用此方法来跳过空白字符 block 等。我发现 JIT 编译器正在优化它,当我这样调用它时:

// Skip white space
this.reader.TakeWhile(IsWhiteSpace);//.FirstOrDefault();

我尝试添加 [MethodImpl(...)] 属性来指示 JIT 编译器不要优化该方法,但它不起作用。现在显然我可以编写另一个实现来操纵底层流缓冲区位置,但出于好奇我想知道为什么会这样。

我发现阻止优化的唯一方法是使用 IEnumerable 结果(例如 - 通过调用 .FirstOrDefault() 如上所述)或将代码复制到调用方法中。我尝试使用 MethodImplAttribute 来阻止调用方法的优化,但这不起作用。奇怪的是,优化在调试版本下完全关闭,所以它不应该在任何情况下发生。有谁知道另一种防止优化的方法?

最佳答案

不,JIT 没有优化它。但是,您的任何代码都不会执行 - 因为您忽略了返回值。在第一次调用 MoveNext() 之前,迭代器 block 中的所有代码都不会运行。这与 JIT 无关,而与迭代器 block 的工作方式有关。

您可能想阅读我关于迭代器 block 的文章(basicsimplementation details)和 Eric Lippert 的“心理调试”博文(part 1part 2)。

请注意,调用 FirstOrDefault() 只会读取第一个 字符。听起来您真的想要消耗整个流直到条件失败 - 这意味着使用 Count() 之类的东西将遍历整个返回的序列。

或者 - 最好是 IMO - 编写一个返回类型为 void 的“事件”方法来执行此操作。如果您对方法的返回值不感兴趣,则表明它可能不是理想的调用方法。 (情况并非总是,但通常如此。)

关于c# - 如何防止 JIT 编译器优化此方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5105760/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com