Предположим, у меня есть математическое выражение в виде «дерева» в OCaml. Он представлен в виде алгебраического типа следующим образом:
type expr =
Number of int
|Plus of expr*expr
Ну, это очень упрощенное определение, но его достаточно, чтобы описать проблему.
Я хочу преобразовать его в строку в обратной полировке. обозначение, так что Plus (Number i, Number j)
становится (+ ij)
. Простая реализация была бы
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^")")
Но дело в том, что это ' s невероятно медленный на некоторых входных данных (которые имеют большую глубину дерева). Например, на моей машине этот ввод работает 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?