Предположим, у меня есть математическое выражение в форме дерева в OCaml.Он представлен в виде алгебраического типа, подобного следующему:
type expr =
Number of int
|Plus of expr*expr
Что ж, это очень упрощенное определение, но этого достаточно для описания проблемы.
Я хочупреобразовать его в строку в обратной польской записи, чтобы Plus (Number i, Number j)
стало (+ i j)
.Простая реализация была бы
let rec convert = function
Number i -> string_of_int i
|Plus (a,b) -> (let s = convert a in let p = convert b in "(+"^s^" "^p^")")
Но дело в том, что невероятно медленно на некотором входе (который имеет большую глубину дерева).Например, этот ввод работает на моей машине 5 секунд:
let rec make_pain so_far = function
0 -> so_far |i -> make_pain (Plus (Number 1,so_far)) (i-1)
let pain = make_pain (Number 1) 20000
let converted = convert pain
Кажется, что конкатенация строк x^y
, где y
- длинная строка, является проблемой производительности.Действительно, если я заменим выражение "(+"^s^" "^p^")"
простым s^p
, оно станет на намного быстрее.
Использование printf
вместо конкатенации не сделает его быстрее.Преобразование в C может помочь, но разве нет решения OCaml?