【问题标题】:2 questions regarding implementation of memoization关于memoization实施的2个问题
【发布时间】:2011-08-20 21:09:29
【问题描述】:

我有这样的课程:

Public NotInheritable Class F
    Private Sub New()
    End Sub
    Public Shared Function Mize(Of TResult)(ByVal f As System.Func(Of TResult)) As System.Func(Of TResult)
        Dim is_new = True
        Dim result As TResult
        Return Function()
                   If is_new Then
                       result = f()
                   End If
                   Return result
               End Function
    End Function
    Public Shared Function Mize(Of T, TResult)(ByVal f As System.Func(Of T, TResult)) As System.Func(Of T, TResult)
        Dim is_new_s = New System.Collections.Generic.List(Of Boolean)
        Dim inputs = New System.Collections.Generic.List(Of T)
        Dim d = New System.Collections.Generic.Dictionary(Of T, TResult)

        Return Function(arg1 As T)
                   If d.ContainsKey(arg1) Then
                       Return d.Item(arg1)
                   Else
                       Dim result = f(arg1)
                       d.Add(arg1, result)
                       Return result
                   End If
               End Function
    End Function End Class

我想知道

1) 这是否违反了static classes should not have state这句话?

2) 我怎样才能修改函数,使它们可以接受任何函数(而不是我上面只适用于F(TResult)F(T, TResult) 的情况。我的意思是我可以创建另一个函数:

Function Mize(Of T, T2, TResult)(ByVal f As System.Func(Of T, T2, TResult))
                                                 As System.Func(Of T, T2, TResult)

等等,但显然它根本不能很好地扩展。

【问题讨论】:

  • 我觉得它更像是“静态类应该避免状态”
  • @Pace:你真的不需要用“vb C# .net”开始每个问题
  • @John Saunders 我认为这会使问题更加“可见”..
  • @Pacerier:请不要为了能见度而那样标记它们。如果是 VB.NET 问题标签,则为 [vb.net]。我们最不需要的就是让它变得像 [c][c++] 标签一样。
  • @Jeff Mercado 我不太明白你想说什么,但没关系。

标签: .net vb.net function memoization


【解决方案1】:

由于泛型在 .NET 中的工作方式,不可能用任何采用任意数量泛型参数的 .NET 语言编写泛型函数。

您最好的选择是:

  1. 为任意数量的参数(例如 10 或 20 个?)创建代码变体,就像 System.Func<TResult, T1, T2, T3, ...> 所做的那样

  2. 使用Objects 作为键(和Delegates 作为函数),而不是泛型类型。这会降低类型安全性并可能导致速度急剧下降,您应该仅在调用DynamicInvoke 的成本超过您的函数速度时才使用它

  3. 使用支持模板的不同语言,例如 C++、D 或 Scheme(这不是一个非常简单的选择,但我还是提到了它)。

    例如在某些语言中,记忆很容易,例如 D:

    auto memoize(alias F, T...)(T args)
    {
        auto key = tuple(args); //Pack args into one
        static typeof(F(args))[typeof(key)] cache; //Dictionary
        return key in cache ? cache[key] : (cache[key] = F(args));
    }
    

    可以很容易地使用:

    result = memoize!(func)(args);  //Calls a memoized 'func' with args
    

不,您的示例不违反状态原则,因为您的静态类保持状态! (你真的是每次都捕获一个局部变量,而不是重用以前的任何东西。)不过我的确实如此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 2020-04-16
    相关资源
    最近更新 更多