Предположим, у меня есть язык, в который я могу ввести выражение, как в этом упрощенном примере:
if A() > B() then A() else B() end
Так что A () и B () - функции, и выражение возвращает большее из двух.Наивный способ оценки этого - вызвать A и B, а затем снова вызвать самый большой из двух.Таким образом, если A возвращает 10, а B возвращает 20, B больше и будет вызываться дважды.
То, что я хотел бы реализовать, это механизм, который бы понимал и что, поскольку A () и B () являются детерминированными (всегда дают один и тот же результат), выражение можно переписать так:
tmpA = A()
tmpB = B()
if tmpA > tmpB then tmpA else tmpB end
Этот код будет вызывать A и B только один раз, если оба одинаково дороги, это сэкономит 33% времени выполнения.
Я хочу сделать это, чтобы пользователю не приходилось беспокоиться о производительности, мой язык ориентирован на бизнес-пользователей, а не на программистов.Пользователь вводит выражения так же, как и он, на доске, программа анализирует их в дереве выражений, и оптимизатор автоматически переписывает их для эффективного выполнения, а затем компилирует.
Кто-нибудь знает хорошую книгу или ресурс, посвященный этой теме?Есть ли какая-то формальная теория по этому поводу?Случай выше легко заметить, но когда все усложняется, я нервничаю.Когда я переписываю выражение и изменяю поведение, которое было бы нехорошо.
Более сложный пример:
A = 10
B = if A > 5 then 100 else 0 end
C = if A > 5 then B * 2 else 0 end
Я не буду утомлять вас всеми деталями, нопредположим, что A - это флаг, который указывает, нужно ли что-то делать.Промежуточная функция B также является результатом, который пользователь может вызвать.
Если я позвоню C, он проверит наличие A> 5, а затем вызовет B, который снова проверит A и вернется.поэтому, когда я подставляю (встроенные) выражения, я получаю
C = if A > 5 then if A > 5 then 100 else 0 end * 2 else 0 end
, который можно оптимизировать до
C = if A > 5 then 200 else 0
. В типичной модели существуют сотни этих выражений, каждый из которых вызывает друг друга.рекурсивный, так что эти вещи могут быть довольно сложными.Если возможно, я бы хотел не выяснять это с помощью проб и ошибок, а узнать, что другие сделали в этой области.
Заранее спасибо,
Герт-Ян