F# 向下转型慢?
F# Downcasting Slow?
我有一种情况需要使用 :?>
在一个过程中向下转型两次。我有一个自定义 EventArgs
class(它继承了 System.EventArgs
),并且在该自定义 EventArgs
中有一个抽象 class 的实例。收到事件后,我需要沮丧两次。一次用于自定义 EventArgs
,一次用于该自定义 EventArgs
中的摘要 class。我每天可能必须执行此操作数百万次,所以我想知道向下转型是否存在固有的缓慢问题。
为了 grins,我整理了以下小函数:
let castToStream (o:Object) = o :?> Stream
并使用以下代码调用它:
[<EntryPoint>]
let main argv =
let stm1 = new FileStream("output.tmp", FileMode.Create, FileAccess.ReadWrite, FileShare.Read)
let obj = stm1 :> Object
let stm2 = castToStream obj
0 // return an integer exit code
编译的时候castToStream
变成这个IL:
.method public static class [mscorlib]System.IO.Stream
castToStream(object o) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: unbox.any [mscorlib]System.IO.Stream
IL_0007: ret
} // end of method Program::castToStream
在这种情况下实际上是 1 条实际指令,unbox.any。 Unbox.any 对于引用类型等同于 castclass 指令。来自 the description, you'll take a one-time initial hit to load the type if it's not already loaded, then it's going to be a whatever magic is necessary to determine if the types are equivalent (likely using Type.IsAssignableFrom(),但我不确定)。但是,除非您的 class 层次结构超深(不应该如此),否则我预计这在典型机器上需要 微秒。
出于好奇,我最初拥有内联 castToStream 的代码,但 f# 编译器识破了我的恶作剧并完全删除了所有转换。
我有一种情况需要使用 :?>
在一个过程中向下转型两次。我有一个自定义 EventArgs
class(它继承了 System.EventArgs
),并且在该自定义 EventArgs
中有一个抽象 class 的实例。收到事件后,我需要沮丧两次。一次用于自定义 EventArgs
,一次用于该自定义 EventArgs
中的摘要 class。我每天可能必须执行此操作数百万次,所以我想知道向下转型是否存在固有的缓慢问题。
为了 grins,我整理了以下小函数:
let castToStream (o:Object) = o :?> Stream
并使用以下代码调用它:
[<EntryPoint>]
let main argv =
let stm1 = new FileStream("output.tmp", FileMode.Create, FileAccess.ReadWrite, FileShare.Read)
let obj = stm1 :> Object
let stm2 = castToStream obj
0 // return an integer exit code
编译的时候castToStream
变成这个IL:
.method public static class [mscorlib]System.IO.Stream
castToStream(object o) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: unbox.any [mscorlib]System.IO.Stream
IL_0007: ret
} // end of method Program::castToStream
在这种情况下实际上是 1 条实际指令,unbox.any。 Unbox.any 对于引用类型等同于 castclass 指令。来自 the description, you'll take a one-time initial hit to load the type if it's not already loaded, then it's going to be a whatever magic is necessary to determine if the types are equivalent (likely using Type.IsAssignableFrom(),但我不确定)。但是,除非您的 class 层次结构超深(不应该如此),否则我预计这在典型机器上需要 微秒。
出于好奇,我最初拥有内联 castToStream 的代码,但 f# 编译器识破了我的恶作剧并完全删除了所有转换。