caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: "Michael D. Adams" <mdmkolbe@gmail.com>
To: caml-list@inria.fr
Subject: Efficency of varient types
Date: Fri, 25 Nov 2005 17:53:54 -0600	[thread overview]
Message-ID: <c62c8d860511251553k782c574cg37fa1116d6fc3064@mail.gmail.com> (raw)

I have recently learned about OCaml and have been impressed by how
fast it is in the benchmarks.  However I have discovered that variant
types can slow down a program quite a bit.  For example, consider the
Ackermann function implemented for int (see program 1) and the same
Ackermann function implemented for a "type value = Int of int | String
of int" (program 2).  The second one is ten times slower!  (Using
ocamlopt.)

I am working on a program that translates code from scheme into ocaml.
 (Later I will try python into ocaml.)  Because it is a dynamicly
typed language, the most natural translation would make everything a
function of a large variant type like:

type value = Int of int
  | Char of char
  | String of string
  (* etc. *)

However the point of my project is to translate into *efficient* ocaml
code so I would like to avoid the ten times slow down that I've seen
with variant types.

Is there is a way to make program 2 as fast as program 1?  (Still
keeping the variant type of course.)

Why is program 2 so slow?  Is it the cost of heap allocation?  The GC?
 Having to access memory instead of registers?  Constructor matching?

One trick that I've thought of would be to push some of the tag
information into the pointer.  For example an Int would be represented
exactly like an int (i.e. an odd address), but a String would be
represented as a pointer to a block (i.e. an even address).  I could
hack around with the Obj module (indeed some experiments with that
show very good performance), but it would be nice if there were a
cleaner way such as a way to annotate constructors so OCaml tries to
avoid using blocks for them.  (Stuffing tags into pointers is very
common in the Scheme world.)

Along those lines, what does the OCaml GC do when it finds an even but
not multiple of 4 pointer?  Somewhere in the documentation it noted
that everything is allocated on 4 byte boundaries so in theory the GC
could ignore everything that is not 4 byte aligned, not just odd
pointers.  This would leave more bits available for stuffing the tag
into the pointer.  For example, XX1 could be an Int constructor, 110 a
char constructor, 010 a bool constructor and X00 be a pointer to any
of the constructors that are represented with blocks.

Michael D. Adams
mdmkolbe@gmail.com

(* Program 1 *)
(*************)
let rec ack m n =
  if m = 0 then n + 1
  else if n = 0 then ack (m - 1) 1
  else ack (m - 1) (ack m (n - 1))

let _ = ack 3 9

(* Program 2 *)
(*************)
type value = Int of int | String of string

let zero = Int 0
let one = Int 1
let plus x y = match x,y with
  | Int x,Int y -> Int (x + y)
let minus x y = match x,y with
  | Int x,Int y -> Int (x - y)

let rec ack m n =
  if m = zero then plus n one
  else if n = zero then ack (minus m one) one
  else ack (minus m one) (ack m (minus n one))

let _ = ack (Int 3) (Int 9)


             reply	other threads:[~2005-11-25 23:53 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-11-25 23:53 Michael D. Adams [this message]
2005-11-26  0:31 ` [Caml-list] " Nicolas Cannasse
2005-11-26  1:22   ` Brian Hurt
2005-11-26  9:39     ` Nicolas Cannasse
2005-11-28  0:17     ` Obj or not Obj Christophe Raffalli
2005-11-28  8:41       ` [Caml-list] " Nicolas Cannasse
2005-11-28  9:27         ` Christophe Raffalli
2005-11-28  9:33         ` skaller
2005-11-28  8:43       ` Alain Frisch
2005-11-26  2:54   ` [Caml-list] Efficency of varient types skaller
2005-11-27  5:06   ` Michael D. Adams
2005-11-27  5:45     ` Brian Hurt
2005-11-27 10:02       ` Nicolas Cannasse
2005-11-27 15:35       ` Michael D. Adams
2005-11-27 18:08         ` Brian Hurt
2005-12-02 15:07           ` Michael D. Adams
2005-11-26  1:18 ` Jon Harrop
2005-11-27 14:57 ` Lukasz Stafiniak
2005-11-27 15:47   ` Lukasz Stafiniak
2005-11-28  8:14   ` Christophe Raffalli
2005-11-28  7:24 ` David Baelde
2005-11-28  7:49   ` Jacques Garrigue
2005-11-28 10:01     ` Jon Harrop
2005-11-28 10:26       ` Luc Maranget
2005-11-28  7:53   ` Ville-Pertti Keinonen
2005-12-01 17:05 ` Stefan Monnier
2005-12-02 15:07   ` [Caml-list] " Michael D. Adams

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c62c8d860511251553k782c574cg37fa1116d6fc3064@mail.gmail.com \
    --to=mdmkolbe@gmail.com \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).