Skip to content

Make typedefof more efficient #5019

@ForNeVeR

Description

@ForNeVeR

I don't think it's actually a suggestion, so I'm filing it as a compiler issue.

As @rspeele mentions in comment to TaskBuilder.fs repo, currently typedefof looks rather inefficient. Compare the following C# and the following F# snippets:

using System.Collections.Generic;
public class C {
    public void M() {
        var x = typeof(List<>);
    }
}
open System.Collections.Generic
type C() =
    member this.M() =
        let x = typedefof<List<_>>
        ()

C# compiles to the following CIL:

         ldtoken [mscorlib]System.Collections.Generic.List`1
         call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
         stloc.0

While F# compiles to the following:

         ldtoken class [mscorlib]System.Collections.Generic.List`1<object>
         call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
         stloc.1
         ldloc.1
         callvirt instance bool [mscorlib]System.Type::get_IsGenericType()
         brfalse.s IL_001b
         
         ldloc.1
         callvirt instance class [mscorlib]System.Type [mscorlib]System.Type::GetGenericTypeDefinition()
         br.s IL_001c
         
IL_001b: ldloc.1
IL_001c: stloc.0

which is an equivalent of

Type typeFromHandle = typeof(List<object>);
Type type = (!typeFromHandle.IsGenericType) ? typeFromHandle : typeFromHandle.GetGenericTypeDefinition()

Could we improve that? Are there any issues I miss with plain ldtoken that require the current approach?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    New

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions