Version franēaise
Home     About     Download     Resources     Contact us    

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

Browse thread
[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 <thelema314@g...>
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);

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)
	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...