Теория переписывания выражений для их оптимизации - PullRequest
2 голосов
/ 09 сентября 2011

Предположим, у меня есть язык, в который я могу ввести выражение, как в этом упрощенном примере:

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

. В типичной модели существуют сотни этих выражений, каждый из которых вызывает друг друга.рекурсивный, так что эти вещи могут быть довольно сложными.Если возможно, я бы хотел не выяснять это с помощью проб и ошибок, а узнать, что другие сделали в этой области.

Заранее спасибо,

Герт-Ян

1 Ответ

0 голосов
/ 09 сентября 2011

Просто мысль, но если вы заставите свой код заменить все дублированные вызовы методов ссылкой на предварительно заполненную переменную (заполненную в строке до ее первого вызова, чтобы избежать ненужных вызовов), вы можете не позволить компилятору выбиратьдо остального ..

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

просто предложение, хотя

...