【问题标题】:How do I translate this code into an expression tree?如何将此代码转换为表达式树?
【发布时间】:2010-02-12 15:00:34
【问题描述】:

我有一个散列方法,其操作取决于函数的输入。分析程序表明,评估此哈希方法花费了太多时间。我想尝试将其更改为表达式树,因此可以进行一次内部循环检查。希望它会更快,但无论如何我都会学习表达式树。

这是该函数的简化版本(我为示例取消了一些明显的优化,并取出了任何输入验证):

Private Function Checksum(ByVal inputValues As IEnumerable(Of UInt32),
                          ByVal declarations As IEnumerable(Of String),
                          ByVal statements As IEnumerable(Of String)) As UInt32
    Dim variables = New Dictionary(Of Char, UInt32)

    For Each declaration In declarations
        'parse declaration (eg. "X=52")'
        variables(declaration(0)) = UInt32.Parse(declaration.Substring(2))
    Next declaration

    For Each value In inputValues
        '"I"nput'
        variables("I"c) = value

        For Each statement In statements
            'parse statement (eg. "X=Y+Z")'
            Dim varResult = statement(0)
            Dim valueLeft = variables(statement(2))
            Dim operand = statement(3)
            Dim valueRight = variables(statement(4))

            'execute statement'
            Dim valueResult As UInt32
            Select Case operand
                Case "+"c : valueResult = valueLeft + valueRight
                Case "-"c : valueResult = valueLeft - valueRight
                Case "*"c : valueResult = valueLeft * valueRight
                Case "&"c : valueResult = valueLeft And valueRight
                Case "|"c : valueResult = valueLeft Or valueRight
                Case "^"c : valueResult = valueLeft Xor valueRight
            End Select
            variables(varResult) = valueResult
        Next statement
    Next value

    '"O"utput'
    Return variables("O"c)
End Function

我想创建一个函数,它接受声明和语句并输出一个专门的表达式树,表示一个函数,该函数接受 UInt32 的 IEnumerable 并返回 UInt32。


跟进:

我成功了,加速是荒谬(一个数量级)。我必须学习的主要内容:

  • 使用 Expression.Lambda 和 Expression.Compile 获取您可以实际使用的委托。
  • Expression.Block 工厂方法有一个“变量”参数,您(本质上)用来声明局部变量。同样,Expression.lambda 具有“参数”。
  • 如果您调用 Expression.Parameter 两次,您将处理两个不同的变量(即使它们的名称相同)!存储结果以供以后使用。标签等也是如此。
  • BlockExpression 的结果是块中的最后一个表达式。

【问题讨论】:

  • 计算哈希值似乎是一种非常复杂的方法。有什么理由必须这样做吗?
  • 它是登录到服务器期间提供的校验和的一部分。我无法控制要计算的内容,只能控制如何计算。

标签: .net vb.net expression-trees


【解决方案1】:

VS 2010 RC 有一个文档更新。我在这里添加了一些关于新 ET API 的示例:http://msdn.microsoft.com/en-us/library/bb397951(VS.100).aspx 它展示了如何创建局部变量以及如何执行表达式树。 VB 和 C# 都有示例。

但老实说,我仍然不明白您要做什么。为什么您的声明和语句以字符串形式出现?而这个 OpToExp 函数对我来说也是一个谜。您是如何设法将操作数作为表达式获取的,但运算符(由于某种原因,您将其称为“操作数”)作为字符? 如果您提供有关您正在尝试做的事情和系统整体设计的更多信息,我可能会为您提供更好的帮助。

【讨论】:

  • 我同意你的观点,这个功能设计得很糟糕。但这是服务器使用的哈希。我需要实现它才能登录,我无法更改它。操作数/运算符是一个愚蠢的错误,哎呀。 操作数是表达式,因为它们在传递给函数之前被解析,而操作符不是。
  • 这正是我所需要的。
猜你喜欢
  • 2018-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-15
  • 1970-01-01
  • 2020-01-13
相关资源
最近更新 更多