[racket] flexpt being very slow

From: Neil Toronto (neil.toronto at gmail.com)
Date: Tue Sep 10 05:15:45 EDT 2013

On 09/09/2013 03:29 PM, Dmitry Cherkassov wrote:
> Hi.
> Please consider this program.
> Why is flexpt so slow?
> I get 20 ms vs 669 ms (for flexpt).

I get 40ms vs 400ms in DrRacket with debug info on, and 30ms vs 300ms 
with debug info off. This is pretty much expected behavior.

Racket's `flexpt' is implemented using C's `pow', but checks extra 
special cases to ensure IEEE and ANSI compliance because most `pow' 
implementations aren't compliant.

`pow' itself is pretty slow: once it gets through its own special cases, 
it has to compute a log, an exponential, and a multiplication in 
extended precision. IIRC, the log and exponential may be implemented in 
software because IEEE 754 doesn't require the FPU to implement them to 
be compliant.

In short, `flexpt' does a lot more work than `fl*', so you should expect 
it to be slower.

Racket's JIT inlines `unsafe-fl*' operations (which Typed Racket's 
optimizer turns `fl*' into) but not `unsafe-flexpt' (which is currently 
just an alias for `flexpt'). But given all the other stuff `flexpt' has 
to do, I wouldn't expect the function call overhead to be a big factor.

Neil ⊥

>> ------------------------------------------------------------------------<
> #lang typed/racket
> (require racket/flonum)
> (define Sz 3000000)
> (define test-vec
>      (for/flvector #:length Sz ([i (in-range Sz)]) (random)))
> (: sum-vec : FlVector -> Flonum)
> (define (sum-vec v)
>    (for/fold ([S 0.0]) ([e (in-flvector v)])
>      (fl+ (fl* e e) S)))
> (: sum-vec-expt : FlVector -> Flonum)
> (define (sum-vec-expt v)
>    (for/fold ([S 0.0]) ([e (in-flvector v)])
>      (fl+ (flexpt e 2.0) S)))
> (printf "plain sqr\n")
> (time (sum-vec test-vec))
> (printf "sqr using flexpt\n")
> (time (sum-vec-expt test-vec))
>> ----------------------------------------------------------------------------<
> Thanks.
> P.S Racket version is 5.3.3

Posted on the users mailing list.