From: Nicolas C. <war...@fr...> - 2003-06-16 05:55:41
|
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. 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. Nicolas Cannasse |
From: Brian H. <bri...@ql...> - 2003-06-16 16:06:50
|
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 |