dynamic-language-runtime - 关于DLR call site缓存的一些问题

标签 dynamic-language-runtime

如果我对DLR操作解析方法的理解有误,请指正

DLR 有一些称为调用站点缓存的东西。给定“a+b”(其中 a 和 b 都是整数),第一次它将无法理解 +(加号)运算符以及操作数。因此它将解析操作数,然后解析运算符,并在构建适当的规则后缓存在级别 1 中。

下次以后,如果找到类似的匹配(操作数是整数类型,运算符是+类型),它会查找缓存并返回结果,此后性能将得到提升。

如果我的理解是正确的(如果你认为我的基本理解不正确,请纠正),我有以下问题正在寻找答案

    a) What kind of operations happen in level 1 , level 2 
    and level 3 call site caching in general
     ( i mean plus, minus..what kind)

    b) DLR caches those results. Where it stores..i mean the cache location

    c) How it makes the rules.. any algorithm.. if so could you please specify(any link or your own answer)

    d) Sometime back i read somewhere that in level 1 caching , DLR has 10 rules,
 level 2 it has 20 or something(may be) while level 3 has 100. 
If a new operation comes, then I makes a new rule. Are these rules(level 1 , 2 ,3) predefined?

    e) Where these rules are kept?

    f) Instead of passing two integers (a and b in the example), 
        if we pass two strings or one string and one integer, 
       whether it will form a new rule?

谢谢

最佳答案

a) 如果我正确地理解了这一点,那么目前所有的级别都有效地工作 - 他们运行一个委托(delegate)来测试对规则重要的参数,然后执行操作或记录失败(失败由任一记录在调用站点上设置一个值或对更新方法进行尾调用)。因此每条规则的工作方式如下:

   public object Rule(object x, object y) {
       if(x is int && y is int) {
             return (int)x + (int)y;
       }
       CallSiteOps.SetNotMatched(site);
       return null;
    }

并且在 L0、L1 和 L2 缓存中使用此方法的委托(delegate)。但是这里的行为可能会改变(并且在开发过程中确实改变了很多次)。例如,在某个时间点,L2 缓存是一棵基于参数类型的树。

b) L0 缓存和L1 缓存存储在CallSite 对象上。 L0 缓存是一个单一的委托(delegate),它总是最先运行的。最初这被设置为一个代表,它只是第一次更新网站。其他调用尝试执行调用站点看到的最后一个操作。

L1 缓存包括调用站点看到的最后 10 个操作。如果 L0 缓存失败,将尝试 L1 缓存中的所有委托(delegate)。

L2 缓存位于 CallSiteBinder 上。 CallSiteBinder 应该在多个调用站点之间共享。例如,假设所有添加都是相同的,通常应该有一个并且只有一个 additiona 语言的调用站点 Binder 。如果 L0 和 L1 将搜索 L2 缓存中的所有可用规则。目前二级缓存上限为128。

c) 规则最终可以通过两种方式产生。一般的解决方案是创建一个 DynamicMetaObject,它包括要执行的操作的表达式树以及确定它是否适用的限制(测试)。这类似于:

public DynamicMetaObject FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg) {
  return new DynamicMetaObject(
       Expression.Add(Expression.Convert(target, typeof(int)), Expression.Convert(arg, typeof(int))),
       BindingRestrictions.GetTypeRestriction(target, typeof(int)).Merge(
           BindingRestrictions.GetTypeRestriction(arg,  typeof(int))
       )
  );
}

这创建了将两个整数相加的规则。这不是真的正确,因为如果你得到的不是整数,它会无限循环——所以通常你会做一堆类型检查,为你能处理的事情产生加法,如果你不能处理则产生错误处理添加。

制定规则的另一种方法是直接提供委托(delegate)。这是更高级的,可以启用一些高级优化来避免一直编译代码。为此,您需要重写 CallSiteBinder 上的 BindDelegate,检查参数,并提供一个类似于我在上面键入的 Rule 方法的委托(delegate)。

d) 在 b) 中回答

e) 我相信这和 b) 是同一个问题

f) 如果您设置了适当的限制,则可以(您必须对标准 Binder 执行此操作)。因为限制会失败,因为您没有两个整数,所以 DLR 将探测缓存,当它没有找到规则时,它会调用 Binder 来生成新规则。这条新规则将带着一组新的限制回来,将安装在 L0、L1 和 L2 缓存中,然后将从那时起对字符串执行操作。

关于dynamic-language-runtime - 关于DLR call site缓存的一些问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4622527/

相关文章:

python - 在 ironpython 中导入模块时会发生什么?

clr - .Net 4.0 会包含新的 CLR 还是保留 2.0 版

visual-studio-2010 - 我可以在 C# 4 中实现 method_missing 并让它实际返回一个值吗?

c# - DynamicObject 二元运算的绑定(bind)行为因运算符和操作数而异

.net - "Iron"语言准备好迎接黄金时段了吗?

.net - IronPython 使用命名空间而无需导入

.net - 如何在 VS2008 中实现对自定义 DLR 语言的智能感知支持?

c# - 如何创建 LINQ 表达式来调用方法?

.net - 查询托管环境中接口(interface)的 IronPython 脚本

c# - 如何在动态对象上动态调用方法?