如何通过泛型实现编译时调度?

问题描述 投票:0回答:1

最近我尝试使用泛型实现编译时调度(下面的示例)

public interface IAbstraction
{
    public void Initialize();
}

public sealed class Implementation : IAbstraction
{
    public void Initialize()
    {
    }
}

public sealed class GenericUsage<T> where T : class, IAbstraction
{
    private readonly T _abstraction;

    public GenericUsage(T abstraction)
    {
        _abstraction = abstraction;
    }

    public void CallAction()
    {
        _abstraction.Initialize();
    }
}

public static void Main()
{
    var genericUsage = new GenericUsage<Implementation>(new Implementation());
    genericUsage.CallAction();
}

如您所见,我还明确使用

sealed
关键字作为信号,表明传递给构造函数的类型不可能与 Generic 中使用的类型不同。

在 JIT Asm 方面,我没有看到去虚拟化。呼叫仍在通过 vtable 进行。

是否有机会通过泛型实现编译时调度?也许我错过了一些东西。如果没有,为什么上面的例子不起作用?

c# generics
1个回答
0
投票

有一个 2015 open 问题与您尝试实现的目标非常相似: RyuJIT 调用优化和已知泛型类型的积极内联

来自评论(2018):

对于通过引用类型实例化的泛型,我们不太可能这样做 很快就会实现去虚拟化,因为 jit 只能看到共享的 版本。如果我们以某种方式启用的话,这可能会在未来发生变化 未共享的引用类型实例化或开始研究推测 去虚拟化。

“共享版本”在共享泛型设计

中有更好的解释

这个想法是,对于某些实例化,生成的代码将 除了一些指令之外几乎相同,所以在 为了减少内存占用以及我们花费的时间 jitting这些通用方法,运行时将生成一个单一的 代码的特殊规范版本,可供所有人使用 该方法的兼容实例。

此功能目前仅支持实例化 引用类型,因为它们都有相同的 大小/属性/布局/等等...用于基本类型的实例化 或值类型,运行时将为它们生成单独的代码体 每个实例化。

© www.soinside.com 2019 - 2024. All rights reserved.