Я работаю над языком на F # и при тестировании обнаружил, что среда выполнения тратит более 90% своего времени на сравнение на равенство. Из-за этого язык настолько медленный, что его невозможно использовать. Во время инструментирования функция GetHashCode
занимает довольно высокое место в списке как источник накладных расходов. Происходит то, что во время вызовов методов я использую тела методов (Expr
) вместе с аргументами вызова в качестве ключей в словаре, и это запускает повторные обходы сегментов AST.
Для повышения производительности я хотел бы добавить узлы запоминания в AST.
type Expr =
| Add of Expr * Expr
| Lit of int
| HashNode of int * Expr
В вышеприведенном упрощенном примере я хотел бы, чтобы HashNode
представляло хэш своего выражения, чтобы GetHashCode
не приходилось углубляться в AST, чтобы вычислить его.
При этом я не уверен, как мне переопределить метод GetHashCode
. В идеале я хотел бы повторно использовать встроенный метод хеширования и заставить его каким-то образом игнорировать только HashNode
, но я не уверен, как это сделать.
Скорее всего, мне придется создать свою собственную хэш-функцию, но, к сожалению, я ничего не знаю о хеш-функциях, поэтому сейчас я немного запутался.
Альтернативная идея, которая у меня есть, состоит в том, чтобы заменить узлы уникальными идентификаторами, сохранив при этом эту хэш-функцию, но это внесет дополнительные сложности в код, которых я бы предпочел избегать, если мне это не нужно.
equality
? Встроенная функция F#equal
работает медленно, но в любом случае сравнение дерева будет дорогостоящим. Если вам просто нужно сравнить идентификатор объекта, а не равенство значений, вы можете использовать атрибутCustomEquality
. - person Just another metaprogrammer   schedule 06.08.2017