This site is updated infrequently. For up-to-date information, please visit the new OCaml website at ocaml.org.

[NEWBIE] is there an in-place map?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
 Date: -- (:) From: Edgar Friendly Subject: Re: [Caml-list] [NEWBIE] is there an in-place map?
```Kuba Ober wrote:
> I need functionality of map, but done in such a way that the output array
> is given as the argument, not as a return value. The closest I could get was
>
> let inplace_map f a b = Array.blit (map f a) 0 b 0 (Array.length a)
>
> Arrays a and b are of the same size.
> This seems very inelegant.
>
> One could use an adapter function and iteri, but that adds very noticeable
> overhead, and doesn't seem too elegant either.
>
> let inplace_map f a b = Array.iteri (fun i src -> b.(i) <- f src; ()) a
>
> There must be a better way of doing it, right? The given here is that the
> arrays a and b are there to stay, so we have to use them in-place.
>
> Cheers, Kuba
>

let blit_map f a b =
for i = 0 to (min (Array.length b) (Array.length a)) - 1 do
b.(i) <- f a.(i);
done

I don't see any better way to do this.  I can't see any overhead to
using a for loop like this.  I guess the recursive solution should also
work fast:

let blit_map f a b =
let rec loop i =
if i < 0 then ()
else b.(i) <- f a.(i); loop (i-1)
in
let max_i = min (Array.length a) (Array.length b) in
loop (max_i - 1)

But as I've been finding out in trying to performance tune for the
Shootout, 'for' loops seem faster than even tail-recursion.  I'd say
something about function call overhead, but tail recursion shouldn't
have such.  Maybe the work of updating the loop counter in the recursive
case makes the difference...

E.

```