gpt4 book ai didi

CIL shows `box` ops when the generic type is constrained to a class(当泛型类型被约束到类时,CIL显示`box`操作)

转载 作者:bug小助手 更新时间:2023-10-24 23:43:42 31 4
gpt4 key购买 nike



I have the following method:

我有以下方法:


public static bool EquivalentTo<T>(this T? current, T? compare)
where T : class
{
if (current is null && compare is null)
// both are null
return true;

if (current is null || compare is null)
// one is null, but not both
return false;

return current.Equals(compare);
}

IL Spy gives the following IL in Release build:

IL Spy在发布版本中提供了以下IL:


.method public hidebysig static 
bool EquivalentTo<class T> (
!!T current,
!!T compare
) cil managed aggressiveinlining
{
.custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = (
01 00 00 00
)
.param type T
.custom instance void [System.Runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = (
01 00 01 00 00
)
// Method begins at RVA 0x4971
// Header size: 1
// Code size: 54 (0x36)
.maxstack 8

IL_0000: ldarg.0
IL_0001: box !!T
IL_0006: brtrue.s IL_0012

IL_0008: ldarg.1
IL_0009: box !!T
IL_000e: brtrue.s IL_0012

IL_0010: ldc.i4.1
IL_0011: ret

IL_0012: ldarg.0
IL_0013: box !!T
IL_0018: brfalse.s IL_0022

IL_001a: ldarg.1
IL_001b: box !!T
IL_0020: brtrue.s IL_0024

IL_0022: ldc.i4.0
IL_0023: ret

IL_0024: ldarg.0
IL_0025: box !!T
IL_002a: ldarg.1
IL_002b: box !!T
IL_0030: callvirt instance bool [System.Runtime]System.Object::Equals(object)
IL_0035: ret
} // end of method Extensions::EquivalentTo

I compiled with Visual Studio 2022 and .Net 8.0.100-preview.7.23376.3 in 64-bit.

我是用64位的Visual Studio 2022和.Net 8.0.100-preview.7.23376.3编译的。


I don't understand why there is boxing when the generic type is constrained to a class and thus cannot be a value type. What am I missing?

我不明白当泛型类型被约束到一个类从而不能是值类型时,为什么会有装箱。我遗漏了什么?


更多回答

CIL isn't optimized at compile-time, optimization is a jitter duty and happens at runtime. Use Debug > Windows > Disassembly to see that the box generates no code.

CIL不是在编译时优化的,优化是一种抖动任务,在运行时发生。使用“调试”>“窗口”>“反汇编”可以看到该框不生成任何代码。

I guess Roslyn just doesn't perform this optimization, but it shouldn't affect performance since boxing a class is no-op and will be eliminated by JIT. Only downside is that each instruction adds 5 byte to result assembly, which may be significant if a lot of such checks are performed

我猜Roslyn只是不执行这种优化,但它不应该影响性能,因为装箱一个类是没有操作的,将被JIT消除。唯一的缺点是每条指令都会向结果汇编添加5个字节,如果执行了大量此类检查,这可能会很重要

优秀答案推荐

box !!T br.true or br.false sequence is always a no-op for structs.

Box!!t br.true或br.False序列始终是结构的无操作。


Since the JITter compiles separate code for all struct (valuetype) generic code, it can see that a box would never result in a null, so it is elided. In the case of classes (reference types) it just does a normal null check.

因为抖动为所有结构(值类型)泛型代码编译单独的代码,所以它可以看到框永远不会导致空值,因此它被省略。对于类(引用类型),它只执行正常的空检查。


You can see this if you look at the JIT ASM machine code that is generated for both structs and classes.

如果您查看为结构和类生成的JIT ASM机器码,就可以看到这一点。


更多回答

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