On Fri, Oct 01, 2021 at 12:03:22PM +0100, Richard W.M. Jones wrote:
BTW as an aside the implementation of the two types of constructors
is
completely different, and polymorphic variants have a slower
implementation. For ordinary constructors they generally map to
integers, which makes them very efficient (eg. they can be stored in
registers etc). Polymorphic variants use a hash of the name instead
making them slower overall.
I mean it's slower not because of the hash - which is computed at
compile time - but because various tricks cannot be used at runtime
which are applicable to small ints.
eg. For the types:
type t = AAA | BBB | CCC
type pv = [`AAA | `BBB | `CCC]
and functions:
let ft = function AAA -> 0 | BBB -> 1 | CCC -> 2
let fpv = function `AAA -> 0 | `BBB -> 1 | `CCC -> 2
the first function is an identity (because the input and output have
the same runtime representation). It only forces the LSB to be set,
for unclear reasons, I think this may be a missed optimization:
camlTest__ft_86:
sarq $1, %rax ; %rax /= 2
leaq 1(%rax,%rax), %rax ; %rax = 2*%rax+1
ret
but the second function requires a bunch of work to deal with the hash
values:
camlTest__fpv_89:
cmpq $6593797, %rax
je .L101
cmpq $6693703, %rax
jl .L102
movl $5, %eax ; return OCaml int 5 = C int 2
ret
.align 4
.L102:
movl $1, %eax ; return OCaml int 1 = C int 0
ret
.align 4
.L101:
movl $3, %eax ; return OCaml int 3 = C int 1
ret
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
Read my programming and virtualization blog:
http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html