Well, actually, pattern matching is compiled to optimize access to fields depending on their types, so the version without Obj is probably actually faster than the version with Obj. Also, the test with 254 should probably not be removed, as records can also be represented using double arrays (actually, your record rec3 will be represented as a double_array). That's the reason why using Obj to optimize code is often not a very good idea, as you lose the type information, and type information is important for faster access to data structures. --Fabrice On 03/16/2011 03:22 AM, Guillaume Yziquel wrote: > Le Tuesday 15 Mar 2011 à 12:05:31 (-0400), Nicolas Ojeda Bar a écrit : >> Hello, >> >> This is not very efficient. I can use Obj.magic to access that same field as >> follows: >> >> let rec2_b x = >> Obj.obj (Obj.field (Obj.field (Obj.repr x.children 0) 0)) > > Seems that you messed up some parentheses. > >> My question is: is this use of Obj safe? and is this compiled to (two) simple >> array accesses? Or is Obj.obj doing something behind the scenes? > > yziquel@seldon:~/sandbox/ocaml$ cat a.ml > let f x = Obj.obj (Obj.field (Obj.field (Obj.repr x) 0) 0) > yziquel@seldon:~/sandbox/ocaml$ ocamlopt -c -S -dlambda a.ml > (seq > (let > (f/1030 > (function x/1031 > (id (array.unsafe_get (array.unsafe_get (id x/1031) 0) 0)))) > (setfield_imm 0 (global A!) f/1030)) > 0a) > > So it should be compiled to array accesses. However, they are not so > simple array accesses due to OCaml data layout. Moreover, there's this > 'id' around. Let's see: > > yziquel@seldon:~/sandbox/ocaml$ cat a.s > > [...] > > camlA__f_1030: > subq $8, %rsp > .L103: > movq %rax, %rdi > movzbq -8(%rdi), %rax > > So the stack has been managed, and the %rax registers now contains the > tag of the 'x' argument to 'f'. > > cmpq $254, %rax > > This checks that the tag is or isn't the tag of an array of doubles. > (Obj.double_array_tag is 254). So we shouldn't jump on the ext 'je'. > > je .L102 > movq (%rdi), %rbx > > The register %rbx now contains the first field of 'x'. > > jmp .L101 > > [...] > > .L101: > movzbq -8(%rbx), %rax > > This looks at the tag of the first field of 'x', and checks below if it > is an array of doubles. > > cmpq $254, %rax > je .L100 > movq (%rbx), %rax > > %rax now contains the first field of the first field of 'x'. > > addq $8, %rsp > ret > > And 'f' returns with what you want. > > So, aside from checking if tag is 254, it's essentially two direct array > accesses, and the 'id' function of Obj.repr and Obj.obj is erased. > > external repr : 'a -> t = "%identity" > external obj : t -> 'a = "%identity" > external field : t -> int -> t = "%obj_field" > > You could probably hack the compiler to avoid the tag checking if you > really wanted to avoid the 254 test. That'd require another "%..." to be > implemented I guess. > >> Thanks! >> N >