Как перевести этот код в дерево выражений?

У меня есть метод хеширования, операции которого зависят от ввода функции. Профилирование программы показало, что слишком много времени тратится на оценку этого метода хеширования. Я хочу попробовать превратить его в дерево выражений, чтобы проверки внутреннего цикла можно было выполнить один раз. Надеюсь, это будет быстрее, но я в любом случае узнаю о деревьях выражений.

Вот упрощенная версия функции (я отменил некоторые очевидные оптимизации для примера и убрал любую проверку ввода):

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

Я хочу создать функцию, которая принимает объявления и операторы и выводит специализированное дерево выражений, представляющее функцию, которая принимает IEnumerable из UInt32 и возвращает UInt32.


Следовать за:

Мне это удалось, и ускорение было смехотворным (на порядок). Основное, чему мне пришлось научиться, где:

  • Используйте Expression.Lambda и Expression.Compile, чтобы получить делегат, который вы действительно можете использовать.
  • Фабричный метод Expression.Block имеет параметр «переменные», который вы (по существу) используете для объявления локальных переменных. Точно так же Expression.lambda имеет «параметры».
  • Если вы вызываете Expression.Parameter дважды, вы имеете дело с двумя разными переменными (даже если их имена совпадают)! Сохраните результат для последующего использования. То же самое с этикетками и т.д.
  • Результатом BlockExpression является последнее выражение в блоке.

person Craig Gidney    schedule 12.02.2010    source источник
comment
Это кажется очень сложным способом вычисления значения хеш-функции. Есть ли какая-то причина, по которой это нужно делать именно так?   -  person Kevin Gale    schedule 12.02.2010
comment
Это часть контрольной суммы, предоставляемой при входе на сервер. У меня нет контроля над тем, что вычислять, только как вычислять.   -  person Craig Gidney    schedule 12.02.2010


Ответы (1)


Вышло обновление документации с VS 2010 RC. Я добавил несколько примеров нового ET API здесь: http://msdn.microsoft.com/en-us/library/bb397951(VS.100).aspx Здесь показано, как создавать локальные переменные и как выполнять деревья выражений. Примеры есть как на VB, так и на C#.

Но, честно говоря, я до сих пор не понимаю, что вы пытаетесь сделать. Почему ваши объявления и операторы представлены в виде строк? И эта функция OpToExp для меня тоже загадка. Как вам удалось получить операнды в виде выражений, а оператор (который вы почему-то называете операндом) в виде char? Если вы предоставите больше информации о том, что вы пытаетесь сделать, и об общем дизайне вашей системы, я могу помочь вам лучше.

person Alexandra Rusina    schedule 12.02.2010
comment
Я согласен с вами, что функция плохо разработана. Но это хеш, который использует сервер. Мне нужно реализовать его для входа в систему, и я не могу его изменить. Операнд/оператор был глупой ошибкой, упс. Операнды являются выражениями, поскольку они анализируются перед передачей в функцию, а оператор — нет. - person Craig Gidney; 12.02.2010
comment
Это именно то, что мне нужно. - person Craig Gidney; 12.02.2010