Dear list readers,

to me it seems this benches only the object creation, not the method dispatch.

So the main result here is that object creation is quite expensive, and record field selection is 2 times faster than getting a value by a method.

Just change foo_s to a constant class instance removing the _ parameter.


Max


On 25.10.2017 11:31, Christoph Höger wrote:
Dear OCaml users,

consider the following microbenchmark:

<snip>
class s (z : string)  (y : int)  (x : int) =
  object method z = z method y = y method x = x
end

type t = { x : int; y : int; z : string}

let foo_s _ =
 (new s) "Example" 0 1

let foo_t _ = {x=1; y=0; z="Example"}

let one_s _ = (foo_s ())#x

let one_t _ = (foo_t ()).x

let fac =
  let rec fac n =
    let f =
      let rec f n a = if n <= 1 then a else f (n - (one_s ())) (n * a)  in f (* change one_t to one_s or vice-versa *)
       in
    f n 1  in
  fac
let bench =
  let rec bench n a =
    if n <= 0
    then a
    else (let x = a && ((fac 20) == (20 * (fac 19)))  in bench (n - 1) x)  in
  bench
let test = bench 10000000 true
let main _ = test
</snip>

If I run it with ocamlopt 4.05.0+flambda and -O3, the version that uses one_s takes about 7.5s whereas the one with one_t uses 0.35s. I know that object method lookup is more costly than records, of course. This particular case baffles me, though. Why is the class not completely inlined?

Also as a related question, is there a way to have the lookup semantics of methods without the open recursion part? That is, can I have a class that consists of values, not methods? It would love to have open tuples in some cases. For example, I'd like to write a function that takes a tuple of any length, because it only needs the first element.

thanks,

Christoph