检测 JIT 是否可用

Detecting if JIT is available

检测 JIT 引擎是否以可移植方式可用的规范(如果有的话,否则任何可靠的)方法是什么?

例如,Xamarin.iOS 不支持 JIT,因为 iOS 平台强制执行 DEP。如今,Mono 非常擅长通过解释 lambda 表达式等大多数东西来弥补差距,但有些东西没有(正确)实现,导致运行时异常严重损害性能。

如果可能的话,我想从共享的便携式 Class 库中进行检测。

您可以尝试执行您知道在 AoT 代码上会失败但在 JIT 上不会失败的操作(例如,动态创建类型)并使用 try/catch 块来定义 JIT 是否可用.

可以这样实现(注意只有当链接器设置为"Link All Assemblies"时才会失败):

private static bool? _isJITAvailable = null;
public static bool IsJITAvailable()
{
    if(_isJITAvailable == null)
    {
        try
        { 
            //This crashes on iPhone
            typeof(GenericClass<>).MakeGenericType(typeof(int));
            _isJITAvailable = true;
        }
        catch(Exception)
        {
            _isJITAvailable = false;
        }
    }

    return _isJITAvailable.Value;
}

不过我不会这样做。你真的需要那些 "better performing callbacks" 开始吗?这听起来确实像是过早的优化。

为什么不在运行时测试两个回调的性能?

如果你的比平台的慢,使用平台的。
如果平台的比你的慢,就用你的。

在深入研究 Mono 源代码后,"magic" 构建时 属性 似乎是 FULL_AOT_RUNTIME。例如,System.Reflection.Emit.AssemblyBuilder 是根据这个 属性 未设置的条件编译的,意思是

var canJit = Type.GetType ("System.Reflection.Emit.AssemblyBuilder") != null;

应该能得到我想要的。