Computing value of following polynomial was proposed as a benchmark: fricas (1) -> p := x^24+32*x^21+9*x^18+34*x^12+34*x^10+45*x^3
Type: Polynomial(Integer)
Naive solution have unimpressive speed: fricas )set messages time on Type: List(Polynomial(Float))
fricas Time: 0.04 (IN) = 0.05 sec Simple reformulations do not give better results. However, assuming that we need double precision floating point results we can turn p into a compiled function. First we convert polynomial to use doubles as coefficients: fricas pf := p::POLY(DoubleFloat)
Type: Polynomial(DoubleFloat?)
fricas Time: 0 sec Then we define corresponding function: fricas function(pf,
Type: Symbol
fricas Time: 0 sec Now try it: fricas v := 0.5::SF
Type: DoubleFloat?
fricas Time: 0 sec [dff(v) for i in 1..10000]; fricas Compiling function dff with type DoubleFloat -> DoubleFloat Type: List(DoubleFloat?)
fricas Time: 0.03 (EV) = 0.03 sec Now it is much better, but still slow. Main cost is interpreter loop. Try driver function: fricas do_it(v, Type: Void
fricas Time: 0 sec do_it(v, fricas Compiling function do_it with type (DoubleFloat,
Type: DoubleFloat?
fricas Time: 0.31 (EV) = 0.32 sec This is much better, around half microsecond per evaluation, but still slower than machine arithmetic. Profiling (not shown here) indicated that 99% of time is spent in exponentiation routine. So we would need better formula like Horner rule. |