Assume I have a mathematical expression in a "tree" form in OCaml. It's represented as an algebraic type like this:
type expr =
Number of int
|Plus of expr*expr
Well, this is a very simplified definition, but it's enough to describe the problem.
I want to convert it to a string in a reverse polish notation, so that Plus (Number i, Number j)
becomes (+ i j)
. A straightforward implementation would be
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^")")
But the thing is that it's incredibly slow on some input (that have a big tree depth). For example, this input works 5 seconds on my machine:
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
It seems that string concatenation x^y
, where y
is a long string, is the performance problem. Indeed, if I replace the "(+"^s^" "^p^")"
expression with mere s^p
, it becomes much faster.
Using printf
instead of concatenation doesn't make it any faster. Converting to C might help, but isn't there an OCaml solution?