Version française
Home     About     Download     Resources     Contact us    
Browse thread
Comments welcomed to progr. style / speed of my first ocaml program "Error correcting LDPC decoder"
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jon Harrop <jon@f...>
Subject: Re: [Caml-list] Comments welcomed to progr. style / speed of my first ocaml program "Error correcting LDPC decoder"
On Thursday 15 December 2005 10:33, Andries Hekstra wrote:
> I am an applied scientist in the areas of signal processing and error
> correction at Philips Research. Having done the programming work of my
> computer simulations in C/C++ for almost 10-15 years with increasingly
> mixed feelings about the languange, a friend pointed me to functional
> programming.

You may be interested in my book Objective CAML for Scientists:

  http://www.ffconsultancy.com/products/ocaml_for_scientists

It covers everything you need and is written for people with similar 
backgrounds to your own.

> I welcome comments w.r.t. programming style, esp. when it affects the speed
> of the program.

You don't need to use ";;" in compiled source.

You can replace:

  print_string "LDPC decoder for rate 1 - ";
  print_int ldpc_j;
  print_string "/";
  print_int ldpc_k;
  print_string " Gallager code with length ";
  print_int codewordLength;
  flush stdout

with a call to "Printf.printf".

You can replace:

  fun j -> fun i -> fun x -> 

with

  fun j i x ->

Try to avoid superfluous parentheses:

        if (i < j) then begin

Use Array.sort instead of writing your own "qsort". Use an array of 2-tuples 
(pairs) instead of two arrays and a custom "qsort2" function.

Put a space either side of a bracketed prefix operator, to avoid problems with 
(*):

  qsort (<) a.(i)

Coalesce computations into a single "let () = ...", rather than spreading them 
out over the source.

Spread your code out more:

  let sum a = let rec sum i a = if (i > 0) then a.(i) +. sum (i-1) a else if 
(i = 0) then a.(i) else 0.
      in sum ((Array.length a) - 1) a

  let sum a =
    let rec sum i a =
      if i > 0 then a.(i) +. sum (i-1) a else
        if i = 0 then a.(i) else 0. in
    sum (Array.length a - 1) a

It looks like you might be creating several arrays that are only filled in at 
the end, in which case it is probably better to create them at the end of a 
calculating using something like Array.init.

Your code often has similar looking parts. You can probably factor out a lot 
of common functionality into higher-order functions, reducing code size and 
the number of mistakes at the cost of a little performance due to the 
genericity of the resulting code.

Especially with long variable names, you may be able to shrink your code by 
nesting more. For example, to avoid passing parameters across many function 
calls. This can also conflict with performance but for more subtle reasons.

Use "&&" and "||" rather than "&" and "or".

You often write:

  let x=1 in begin
    for i=1 to 10 do
      ...
    done
  end

when you could write:

  let x=1 in
  for i=1 to 10 do
    ...
  done

Reducing maxNumberOfIterations to 1, the final time given is 78.54s on my 
900MHz 32-bit Athlon and 55.67s on my 800MHz AMD64.

You can shave 2% off the time by factoring the computation of pi from 
randomGaussian. You can reduce the run-time by 25% by using a faster 
randomGaussian function (e.g. the one given in NR) and compiling with 
"-inline 100".

HTH.

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists