这个比较会被编译成泛型class中的常量布尔值吗?
Will this comparison be compiled into a constant Boolean value in a generic class?
typeof(T) == typeof(string)
T 是一个泛型类型参数,是否会被编译成一个常量布尔值,因为条件在编译时是可知的?
通用类型数据存在于 IL 中 - 它不会像 Java 中那样被删除。所以:不,C# 编译器 不会将其编译为常量;它编译了谈论通用类型参数的 IL。
JIT然后重用用于所有引用类型排列(只有每个值类型排列需要单独的 JIT,因为size/boxing/etc 原因)。由于 string
是引用类型,这意味着 Foo<string>
(其中 typeof(T)==typeof(string)
是 true
)使用与 Foo<SomeClass>
(其中 typeof(T)==typeof(string)
是 false
)。所以不:这显然 不是 常量,即使在 JIT 时间也是如此。
我对此做了一些性能测试,结果如下:
- 如果泛型类型是 class(不是结构),则语句没有编译器或运行时优化:if (typeof(T) == typeof(someClass))。
- 如果泛型类型是一个结构体,则对格式的 if 语句进行编译器或运行时优化:if (typeof(T) == typeof(someStruct)),直到某个点(大小该方法似乎很重要:在 998 个 if 语句之后的我的测试装置中)。在这一点之后,性能会急剧下降:虽然在这一点之前添加额外的这种类型的 if 语句不会造成性能损失,但在这一点之后的额外 if 语句会导致性能下降超过 10000%。
- 将泛型类型限制为某个 class 或将其限制为结构不会改变性能。
- 重要的是方法的大小,而不是 class 的大小。因此,10 个方法执行相同操作可能比 1 个大型方法执行得更好。
已在 VS2017 和 .net 4.6.2 上使用 C# 进行测试,并启用了优化。
typeof(T) == typeof(string)
T 是一个泛型类型参数,是否会被编译成一个常量布尔值,因为条件在编译时是可知的?
通用类型数据存在于 IL 中 - 它不会像 Java 中那样被删除。所以:不,C# 编译器 不会将其编译为常量;它编译了谈论通用类型参数的 IL。
JIT然后重用用于所有引用类型排列(只有每个值类型排列需要单独的 JIT,因为size/boxing/etc 原因)。由于 string
是引用类型,这意味着 Foo<string>
(其中 typeof(T)==typeof(string)
是 true
)使用与 Foo<SomeClass>
(其中 typeof(T)==typeof(string)
是 false
)。所以不:这显然 不是 常量,即使在 JIT 时间也是如此。
我对此做了一些性能测试,结果如下:
- 如果泛型类型是 class(不是结构),则语句没有编译器或运行时优化:if (typeof(T) == typeof(someClass))。
- 如果泛型类型是一个结构体,则对格式的 if 语句进行编译器或运行时优化:if (typeof(T) == typeof(someStruct)),直到某个点(大小该方法似乎很重要:在 998 个 if 语句之后的我的测试装置中)。在这一点之后,性能会急剧下降:虽然在这一点之前添加额外的这种类型的 if 语句不会造成性能损失,但在这一点之后的额外 if 语句会导致性能下降超过 10000%。
- 将泛型类型限制为某个 class 或将其限制为结构不会改变性能。
- 重要的是方法的大小,而不是 class 的大小。因此,10 个方法执行相同操作可能比 1 个大型方法执行得更好。
已在 VS2017 和 .net 4.6.2 上使用 C# 进行测试,并启用了优化。