C#优化和副作用

C#优化和副作用,c#,optimization,jit,C#,Optimization,Jit,C#编译器或抖动所做的优化是否会产生明显的副作用 有一个例子我想了一下 var x = new Something(); A(x); B(x); 调用A(x)x时,保证在A结束时保持活动状态,因为B使用相同的参数。但是如果B被定义为 public void B(Something x) { } 然后优化器可以消除B(x),然后可能需要调用GC.KeepAlive(x) 这种优化实际上可以通过抖动来完成吗 除了堆栈跟踪更改之外,还有其他优化可能有明显的副作用吗?如果函数B不使用参数x,那么消除

C#编译器或抖动所做的优化是否会产生明显的副作用

有一个例子我想了一下

var x = new Something();
A(x);
B(x);
调用
A(x)
x
时,保证在
A
结束时保持活动状态,因为
B
使用相同的参数。但是如果
B
被定义为

public void B(Something x) { }
然后优化器可以消除
B(x)
,然后可能需要调用
GC.KeepAlive(x)

这种优化实际上可以通过抖动来完成吗


除了堆栈跟踪更改之外,还有其他优化可能有明显的副作用吗?

如果函数B不使用参数x,那么消除它并尽早收集x不会有任何明显的副作用


要成为“可见的副作用”,它们必须对程序可见,而不是对调试器或对象查看器之类的外部工具可见。

在您的问题中包括
B
,只会混淆问题。鉴于此代码:

var x = new Something();
A(x);
假设
A(x)
是托管代码,那么调用
A(x)
会维护对
x
的引用,因此垃圾收集器在
A
返回后才能收集
x
。或者至少直到
A
不再需要它。JITer所做的优化(没有bug)不会过早地收集
x


你应该定义你所说的“可见的副作用”是什么意思。有人希望JITer优化至少有使你的代码更小或更快的副作用。这些是“可见的”还是“不受欢迎的?”

Eric Lippert已经开始了一个关于重构的伟大系列,这让我相信C#编译器和抖动确保不会引入副作用。和目前在线

当调用A(x)时,x保证在A的末尾保持活动-因为B使用相同的参数

这句话是假的。假设方法A总是抛出异常。抖动可以知道永远不会达到B,因此可以立即释放x。假设方法A在最后一次引用x后进入无条件无限循环;同样,抖动可以通过静态分析知道,确定x永远不会被再次引用,并计划将其清除。我不知道抖动是否真的执行了这些优化;他们看起来很狡猾,但他们是合法的


这种优化(即,对不在任何地方使用的引用进行早期清理)真的可以由JITter完成吗

是的,在实践中,它已经完成了。这不是一个明显的副作用

本规范第3.9节证明了这一点,为方便起见,我引用了该节:

如果该对象或其任何部分不能通过任何可能的继续执行(析构函数运行除外)来访问,则该对象将被视为不再使用,并且它将符合销毁条件。C#编译器和垃圾收集器可能会选择分析代码,以确定将来可能会使用哪些对象引用。例如,如果作用域中的局部变量是对对象的唯一现有引用,但该局部变量从未在过程中从当前执行点开始的任何可能的继续执行中被引用,则垃圾收集器可能(但不要求)将该对象视为不再使用


C#编译器或抖动所做的优化是否会产生明显的副作用

本规范第3.10节回答了您的问题,为方便起见,我在此引用该节:

继续执行C#程序 这样每种药物的副作用 正在执行的线程被保留在 关键执行点

一方 效果定义为读或写 对于易失性字段,对 非易失性变量,对 外部资源,以及 例外

关键执行 在这些点的顺序 必须保留副作用 对易失性字段、锁语句的引用, 以及线程的创建和终止

执行环境是自由的 更改C的执行顺序# 程序,但须符合以下要求 限制条件:

数据依赖性是 保存在一根线内 执行。也就是说,每个 变量的计算方式与 线程中的语句被执行 按原程序顺序

初始化顺序规则是 保存

保留副作用的顺序 关于易失性读取和 写

此外 执行环境不需要 计算表达式的一部分,如果它 可以推断出这个表达式是 未使用值,且不需要该值 产生副作用(包括 任何由调用方法或 访问易失性字段)

什么时候 程序执行被一个命令中断 异步事件(例如 由另一个线程引发的异常), 不能保证 可观察到的副作用在 原始程序顺序

第二段到最后一段我相信是你最关心的一段;也就是说,在影响可观察到的副作用方面,允许运行时执行哪些优化?允许运行时执行任何不影响可观察到的副作用的优化

请注意,特别是数据依赖性仅保留在执行线程中。当从另一个执行线程观察时,不能保证保留数据依赖性

如果这不能回答您的问题,问一个更具体的问题。特别是,如果不考虑ABOV的定义,对“可观察到的副作用”的仔细和精确的定义将有必要更详细地回答您的问题。