[plt-scheme] Float Vectors and Unsafe Operations

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Mon May 17 08:33:22 EDT 2010

At Sun, 16 May 2010 21:22:09 -0600, Doug Williams wrote:
> I am updating the science collection to release shortly after the release of
> Racket. One thing I am doing is using the expanded set of unsafe operations
> where practical - I was only using the basic operations before. When I
> started using the original unsafe operations, I looked into using flvectors
> for some internal data structures, but they turned out to be less efficient
> at the time than regular vectors (that happen to contain floats).
> 1) Would we expect the flvector (or fl64vector) implementations to be more
> efficient now? Or, at sometime in the (near) future?

In the general case, a number has to be boxed every time that it is
extracted from an flvector or f64vector. If the value is immediately
consumed by flonum operation, then the value doesn't have to be boxed,
and that's where performance improvements can kick in. Otherwise, if
the number usually has to be boxed after extracting it from an
flvector, then flvectors can be less efficient than plain vectors
(which hold numbers that are already boxed).

> 2) I assume flvectors are 32-bit floats and fl64vectors are 64-bit floats.
> Is this correct? Is there any significant difference in efficiency of one
> over the other - particularly wrt unsafe operations?

Noel covered this one: both flvectors and f64vectors both store 64-bit
floats, and the difference is an indirection on the array as a whole.

For working with foreign libraries, f64vectors are usually better,
while flvectors can be slightly more efficient when staying in Racket
code with flonum-specific operations. Having both flvectors and
f64vectors gives a programmer control over the trade off, though it is
somewhat confusing.

> 3) Would it be possible for scheme/flonum to export fl64vectors as well as
> flvectors - instead of directly requiring scheme/foreign?

That would make sense if flvector and f64vector stored different kinds
of values. Since f64vector is mainly for foreign interoperability,
though, I think that it's best to keep it in the FFI libraries.

Probably not relevant, but just in case: If you're using the latest, we
didn't simply move `scheme/foreign' to `racket/foreign'. The
`scheme/foreign' library still exists, but it's a compatibility wrapper
for the new organization, where `f64vector' is provided by the safe
library `ffi/vector'.

Posted on the users mailing list.