[racket] flexpt being very slow
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
>