From: Martin Chabr <martin_chabr@yahoo.de>
To: Thomas Fischbacher <Thomas.Fischbacher@Physik.Uni-Muenchen.DE>
Cc: caml-list@yquem.inria.fr
Subject: Ant: Re: Ant: Re: Ant: Re: [Caml-list] Avoiding shared data
Date: Mon, 3 Oct 2005 22:03:37 +0200 (CEST) [thread overview]
Message-ID: <20051003200337.14092.qmail@web26809.mail.ukl.yahoo.com> (raw)
In-Reply-To: <Pine.LNX.4.61.0510031406320.28375@eiger.cip.physik.uni-muenchen.de>
Thomas,
what I am especially concerned about is the stack
overflow for non-tail-recursive programs. Speed is of
less importance.
By the way, we are diverting from the subject of this
thread and from the main cause of my concern:
Avoiding shared data. Why is it done that way? Who
wants to have an array or list of identical records or
sub-arrays or other sub-structures which are all
updated at the same time in the same way? In other
words, who wants to have an array or a list of
pointers which are pointing to the same thing?
Does it ever happen in OCaml if programming is done in
a purely functional way? Does it happen in Haskell?
Martin
--- Thomas Fischbacher
<Thomas.Fischbacher@Physik.Uni-Muenchen.DE> schrieb:
>
> On Mon, 3 Oct 2005, skaller wrote:
>
> > > I hope that one day functional language
> compilers will
> > > do that optimization for you - convert a
> > > non-tail-recursive code into a tail-recursive
> one. Do
> > > you know of some progress in that direction?
> >
> > Isn't that just CPS?
>
> He presumably wanted to see a different thing, e.g.
> automatically transforming
>
>
> let rec fac1 x =
> if x = 0
> then 1
> else x*(fac1 (x-1))
> ;;
>
> into
>
> let fac2 x =
> let rec walk so_far todo =
> if todo = 0
> then so_far
> else walk (todo*so_far) (todo-1)
> in walk 1 x
> ;;
>
>
> My impression is that it may indeed be possible to
> do something like this
> for simple applications, but that the cases that can
> be covered
> automatically presumably are so limited that an
> experienced programmer
> will usually want to attack them by going to a
> higher form of abstraction
> and not waste time on such things anyway.
>
> I think that Olin Shivers indeed does have a valid
> point in pointing out
> that writing loops in tail-recursive style has major
> disadvantages.
> However, my impression still is that as soon as
> someone thinks in terms of
> "I have to write a loop for this", chances are good
> that he may improve
> his design by going back one step and ask the
> question "what do I want to
> use that loop for?". In quite many situations, it is
> possible to express
> one's thoughts more directly via other means, such
> as Array.map,
> fold_left, etc.
>
> What I (as a pedestrian) especially do not like
> about loops is that it is
> much easier to make off-by-one errors than with any
> form of recursion
> which contains a base-case/recursive-case analysis.
>
>
> Unfortunately, the OCaml native code compiler
> apparently is not yet smart
> enough to optimize code written in such a
> higher-order style well enough
> so that it can compete with imperative or
> tail-recursive code in
> time-critical applications. (Though quite many
> applications in fact are
> not.) At present, one can expect to lose about a
> factor of ~3 in
> performance.
>
> Example:
>
> ===>
> let timing_apply f x =
> let t0 = Unix.gettimeofday() in
> let f_x = f x in
> let t1 = Unix.gettimeofday() in
> (f_x,t1-.t0)
> ;;
>
> let my_array_fold_left f init arr =
> let len = Array.length arr in
> let rec walk so_far pos =
> if pos=len
> then so_far
> else walk (f so_far arr.(pos)) (1+pos)
> in walk init 0
> ;;
>
>
> let test m n =
> let arr =
> Array.init m
> (fun j -> Array.init n (fun k -> j*k+k))
> in
> let scratchpad = ref 0 in
> (* -- *)
> let rec frobenius1 mx =
> Array.fold_left
> (fun so_far row ->
> Array.fold_left
> (fun so_far entry ->
> so_far+entry*entry)
> so_far row)
> 0 mx
> in
> let frobenius2 mx =
> my_array_fold_left
> (fun so_far row ->
> my_array_fold_left
> (fun so_far entry ->
> so_far+entry*entry)
> so_far row)
> 0 mx
> in
> let frobenius3 mx =
> begin
> scratchpad := 0;
> for i=0 to (Array.length mx)-1 do
> let row = mx.(i) in
> for j=0 to (Array.length row)-1 do
> scratchpad:= !scratchpad + row.(j)*row.(j);
> done;
> done;
> !scratchpad
> end
> in
> let frobenius4 mx =
> let nr_rows = Array.length mx in
> let rec walk_rows so_far nr_row =
> if nr_row = nr_rows
> then so_far
> else
> let row = mx.(nr_row) in
> let len_row = Array.length row in
> let rec walk_cols so_far nr_col =
> if nr_col = len_row
> then so_far
> else walk_cols (so_far+row.(nr_col)*row.(nr_col))
> (1+nr_col)
> in
> walk_rows (walk_cols so_far 0) (1+nr_row)
> in
> walk_rows 0 0
> in
> let frobenius5 mx =
> let nr_rows = Array.length mx in
> let rec walk_rows so_far nr_row =
> if nr_row = nr_rows
> then so_far
> else
> let row = mx.(nr_row) in
> let len_row = Array.length row in
> let rec walk_cols row so_far nr_col =
> if nr_col = len_row
> then so_far
> else walk_cols row
> (so_far+row.(nr_col)*row.(nr_col)) (1+nr_col)
> in
> walk_rows (walk_cols row so_far 0) (1+nr_row)
> in
> walk_rows 0 0
> in
> let compute_n_times n f x =
> let rec walk k =
> if k = n then f x
> else
> let () = ignore(f x) in
> walk (k+1)
> in walk 1
> in
> Array.map
> (fun f -> timing_apply (compute_n_times 1000 f)
> arr)
>
>
[|frobenius1;frobenius2;frobenius3;frobenius4;frobenius5|]
> ;;
>
> let result = test 1000 3 in
> Array.iteri (fun nr (_,t) -> Printf.printf "%d:
> %f\n" (1+nr) t) result
> ;;
> <===
>
> ocamlc:
>
> 1: 0.987257
> 2: 1.196910
> 3: 0.709074
> 4: 0.858948
> 5: 0.984935
>
> ocamlopt:
>
=== message truncated ===
___________________________________________________________
Gesendet von Yahoo! Mail - Jetzt mit 1GB Speicher kostenlos - Hier anmelden: http://mail.yahoo.de
next prev parent reply other threads:[~2005-10-03 20:03 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-09-25 21:32 Martin Chabr
2005-09-26 0:23 ` [Caml-list] " Bill Wood
2005-09-26 7:57 ` Claudio Sacerdoti Coen
2005-09-26 8:17 ` William Lovas
2005-09-26 21:07 ` Ant: " Martin Chabr
2005-09-26 22:08 ` Jon Harrop
2005-09-30 22:57 ` Oliver Bandel
2005-10-01 0:07 ` Pal-Kristian Engstad
2005-10-01 5:46 ` Bill Wood
2005-10-01 8:27 ` Wolfgang Lux
2005-10-01 18:02 ` Wolfgang Lux
2005-10-01 21:50 ` Ant: " Martin Chabr
2005-10-01 12:34 ` Oliver Bandel
2005-10-01 13:58 ` Bill Wood
2005-10-01 21:05 ` Ant: " Martin Chabr
2005-10-03 0:41 ` skaller
2005-10-03 1:13 ` Seth J. Fogarty
2005-10-03 13:09 ` Thomas Fischbacher
2005-10-03 14:57 ` skaller
2005-10-03 20:03 ` Martin Chabr [this message]
2005-10-03 20:25 ` Ant: " Thomas Fischbacher
2005-10-03 21:08 ` Jon Harrop
2005-10-04 18:06 ` Ant: " Martin Chabr
2005-10-04 18:32 ` Jon Harrop
2005-10-04 2:53 ` skaller
2005-10-04 16:15 ` Brian Hurt
2005-10-04 16:47 ` FP/IP and performance (in general) and Patterns... (Re: [Caml-list] Avoiding shared data) Oliver Bandel
2005-10-04 22:38 ` Michael Wohlwend
2005-10-05 0:31 ` Jon Harrop
2005-10-04 22:39 ` Christopher A. Watford
2005-10-04 23:14 ` Jon Harrop
2005-10-05 12:10 ` Oliver Bandel
2005-10-05 13:08 ` Jon Harrop
2005-10-05 15:28 ` skaller
2005-10-05 20:52 ` Ant: " Martin Chabr
2005-10-05 23:21 ` Markus Mottl
2005-10-06 16:54 ` brogoff
2005-10-05 0:45 ` Brian Hurt
2005-10-04 18:09 ` Ant: Re: Ant: Re: Ant: Re: Ant: Re: [Caml-list] Avoiding shared data Martin Chabr
2005-10-05 8:42 ` skaller
2005-10-05 11:14 ` Andrej Bauer
2005-10-01 21:36 ` Ant: Re: Ant: " Martin Chabr
2005-10-03 11:51 ` getting used to FP-programming (Re: Ant: Re: Ant: Re: [Caml-list] Avoiding shared data) Oliver Bandel
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=20051003200337.14092.qmail@web26809.mail.ukl.yahoo.com \
--to=martin_chabr@yahoo.de \
--cc=Thomas.Fischbacher@Physik.Uni-Muenchen.DE \
--cc=caml-list@yquem.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