caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Nuutti Kotivuori <naked+caml@naked.iki.fi>
To: Jacques Garrigue <garrigue@kurims.kyoto-u.ac.jp>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Object-oriented access bottleneck
Date: Sun, 07 Dec 2003 21:46:20 +0200	[thread overview]
Message-ID: <87brqkcsxf.fsf@iki.fi> (raw)
In-Reply-To: <20031207192702D.garrigue@kurims.kyoto-u.ac.jp>

Jacques Garrigue wrote:
> I think the correct name is "late binding".

Ah, right. Thanks.

> But you're correct. Classes are not very good for performance, and
> nothing serious is done for their optimization.
>
> As you remarked already, the object model chosen in ocaml makes
> final methods mostly irrelevant. There is however one way to tell
> the compiler that a specific method code should be used, but this
> only works for calls inside a class: inherit c ... as super method p
> = ... super#m ...  In this case, if we know statically the class c,
> we exactly know the code referenced by super#m. However, this
> information is not used currently (and is probably not what you want
> for your own code). And there is no way to tell this for a method
> defined in the same class.

Ah, right! So it would be possible to inline the "c"'s method "m" into
the body of method "p" in class "a" - just that the compiler doesn't
do that?

> The approach you suggest of using a record sounds like a good idea.
> This will make the problem clearer: either you really need objects,
> and external functions are just there for performance; or you didn't
> need them anyway, and you will be able to rewrite everything as
> functions with a record parameter.  Note also that this is not as
> clumsy as it looks: even without records, you can already pass (by
> hand) all non-mutable fields to external functions (labelled
> parameters handy there?)

Yeah, that will probably just fine. Just that, in OCaml, unlike for
example CLOS (where method calls look just like ordinary function
calls), normally exposes in an interface if things are objects or not
- obviously so if you are supposed to use method calls. So either I
commit to using objects, or commit to having a simple function-based
interface, which will have to wrap the method calls, if the
implementation ever becomes based on objects.

> If your problem requires objects, I'm interested if you can show me
> some code: I'm in the process of making extensive changes to object
> compilation, and I need serious performance sensitive benchmarks.
> (All my programs using objects call them only a few times, so that
> method calls could be 10 times slower and I wouldn't care)

This is mostly an academic problem for me right now, as I'm just
getting into OCaml. So no actual production code is at hand.

But here is a trivial example, as my weak OCaml skills could produce
it:

,----
| class atom =
| object (self : 'a)
|   val mutable id = 0
|   method get_id () = id
|   method compare (x:'a) =
|     let x_id = x#get_id () in
|       if id < x_id then -1 else if id > x_id then 1 else 0
| end;;
| 
| let atom_compare (x:#atom) (y:#atom) = x#compare y;;
| 
| let sort_atoms x = List.sort atom_compare x;;
`----

Now, it should somehow be possible to translate this into a form where
the body of sort_atoms would be fully inlined with no external
function calls. As I take it, calling List.sort like that in a
traditional program doesn't get inlined yet either? But you get the
idea.

It's good to know that progress is being made on the object front,
especially in terms of performance. Some of these might be doable, I
just don't know how, but a few things that bugged me when I
investigated were:

 - no way to specify the exact type for an argument - atleast not
   without abstract types. If I type:

     let f x = f#m x

   then f will accept any object that has method m. If I type:

     let f (x:#a) = f#m x

   then f will accept any object that has atleast the interface of
   a. If I type:

     let f (x:a) = f#m x

   then f will accept any object that has exactly the interface of a -
   if it's anything else, then it will have to be subtyped to a
   first. But I have no way of saying that accept only class a typed
   parameters, regardless of any subtyping or identical
   interfaces. Except, as said, by making the argument type abstract
   through an interface.

 - no way to have a method/function inside a class that could be used
   by several methods, would have access to class variables and would be
   inlined. It would not need to be visible to the outside. Like
   mentioned, this can be circumvented for non-mutable variables by just
   giving them as parameters.

 - no standard way to have method call like invocation for normal
   function calls. Consider for example:

     Udp.get_data (Ip.get_udp (Eth.get_ip (Packet.as_eth packet)))

   Against the same with a handy definition of let (-->) x f = f x:

     packet --> Packet.as_eth --> Eth.get_ip --> Ip.get_udp --> Udp.get_data

   Or, as actual method calls:

     packet # as_eth # get_ip # get_udp # get_data

Though I'm not sure if you were touching features or syntax at all :-)

Anyhow, that's it for now, thanks for listening,
-- Naked

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


  reply	other threads:[~2003-12-07 19:46 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-12-07  2:39 Nuutti Kotivuori
2003-12-07  2:59 ` Nicolas Cannasse
2003-12-07 11:22   ` Benjamin Geer
2003-12-07 14:12     ` Nicolas Cannasse
2003-12-07 18:04   ` Nuutti Kotivuori
2003-12-07 10:27 ` Jacques Garrigue
2003-12-07 19:46   ` Nuutti Kotivuori [this message]
2003-12-08  1:07     ` Jacques Garrigue
2003-12-08 15:08       ` Nuutti Kotivuori
2003-12-08 15:42         ` Richard Jones
2003-12-09  0:26           ` Nicolas Cannasse
2003-12-09 12:10             ` Nuutti Kotivuori
2003-12-09 13:17               ` Olivier Andrieu
2003-12-09 13:53                 ` Nuutti Kotivuori
2003-12-08 17:51       ` Brian Hurt
2003-12-08 18:19         ` brogoff
2003-12-08 20:09           ` Brian Hurt
2003-12-08 19:02         ` Xavier Leroy
2003-12-08 21:37           ` Brian Hurt
2003-12-08 21:06             ` Nuutti Kotivuori
2003-12-08 22:30             ` malc
2003-12-07 18:23 ` Brian Hurt
2003-12-07 18:14   ` Nuutti Kotivuori
2003-12-07 19:30     ` Brian Hurt
2003-12-07 23:50       ` Abdulaziz Ghuloum
2003-12-08 17:29         ` Brian Hurt
2003-12-08 18:48           ` Nuutti Kotivuori
2003-12-08 10:17       ` Nuutti Kotivuori
2003-12-08 19:51       ` skaller

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=87brqkcsxf.fsf@iki.fi \
    --to=naked+caml@naked.iki.fi \
    --cc=caml-list@inria.fr \
    --cc=garrigue@kurims.kyoto-u.ac.jp \
    /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).