On Mon, 16 Jun 2003, Nicolas Cannasse wrote:
> Recently, after the talks of Xavier Leroy on the main ocaml list, it appear
> that Obj.set_field is not working so good. Jacques Garrigue looked at the
> generated native code and he noticed that the Obj.set_field is doing
> additional (useless) operation by testing the block tag for
> Double_array_tag. Not only the code is bigger, but there is a (very) little
> speed issue , compared to using a mutable structure like :
> type 'a mutlist = { h : 'a ; mutable tl : 'a mutlist; }
> I might then modify ExtList soon to clean theses things.
> ( please note that we still Obj.magic to convert from/to 'a list.
We're already dependent upon the structure of the list object already.
This is probably a good idea. If you don't want to do it, I'll do it.
>
> Another problem might come from the "trick" :
> let x = [ Obj.magic () ] in
> ....
> List.tl x
> who might get outlined by the compiler and thus will be shared by several
> calls (which is not what we want since we're muting the tail !). A
> workaround is not to use unit but one of the arguments of the function to
> prevent to compiler to mark the block as constant.
My preference would be to special case the first element. Picking a
resonably difficult example of how this would work, we'd have:
type 'a mut_list = {hd: 'a; mutable tl: 'a list}
external inj : 'a mut_list -> 'a list = "%identity"
let filter_map f l =
let rec loop2 dst = function
| [] -> ()
| h :: t ->
match f h with
| None -> loop2 dst t
| Some x ->
let r = { hd = x; tl = [] } in
dst.tl <- inj r;
loop2 r t
in
let rec loop1 = function
| [] -> []
| h :: t ->
match f h with
| None -> loop1 t
| Some x ->
let r = { hd = x; tl = [] } in
loop2 r t;
inj r
in
loop1 l
The code is a little bit more complicated, I agree. But we don't have to
worry about magic values. Generally, the less magic we depend upon, the
happier I am.
Brian
|