Serge D. Mechveliani wrote:
> 
> People,
> 
> can you, please, answer the following beginner questions on compilation 
> and performance
> (for  FriCAS-1.1.5 - GNU CLISP 2.48 - Debian Linux). 
>  
> Consider the following program that counts by decreasing n by a string 
> length.
> 
> -- file  ct.input  -------------------------------------
> 
> all x == true
> 
> ct(n : Integer) : Integer  == 
>  
>   str := "abc"
>   i := n
>   while  i > 0  repeat  i := i - count(x +-> true, str)
>   return i
> --------------------------------------------------------
> 
> Is  count(x +-> true, str)  the simplest way to find a string length?
> 
> Is  ct  written in the Spad language?
> 
> After   )r ct
>         all 1
>         ct 9,
> 
> the FriCAS dialogue says that `all' and  ct  have been compiled.
> Is this the same code for `all' and  ct  that is produced from the 
> .spad file?  If not, then has it at least the same performance?

Comparable if you avoid traps...

> Replacing  `x +-> true'  with  `all'  reduces the performance about 10
> times  
> (apply  ct (4*10^5)  for a 1 GHz machine). 
> Why is it so unstable?

In interpreter access to all is done like access to global variable,
which is rather complicated procedure (find variable first, then
try to coerce to correct type).  Access to global variables is
one of interpreter traps, as you see it is slow.  Other trap
are automatic coercions, they are inserted automatically by
the interpreter and can take a lot of run time.  Both traps
are avoided when using Spad compiler.  More precisely, Spad
does not give you easy way to access intepreter variables and
access to Spad "globals" is relatively fast.  In Spad you
need to explicitly add coercions -- if you really need them
they will still take time, but when your code does not compile
due to type mismatch you freqently can change it to avoid
at least some coercions.

> Does this particular performance example depend on the Lisp version?

I tried 5 versions of your code on different Lisp versions:

                        Clisp     ecl        sbcl
ct1(4*10^5)             0.66      0.18       0.08
ct2(4*10^5)             0.72      0.18       0.07
ct3(4*10^5)             5.59      1.08       2.04
ct4(4*10^5)             0.64      0.13       0.05
ct5(4*10^5, all)        0.64      0.14       0.05


ct1 is your original, ct2 uses 'x +-> all(x)' ct3 uses just 'all'
(like your second version), ct4 is:

ct4(n : Integer) : Integer  ==
  fn : Character -> Boolean := all
  str := "abc"
  i := n
  while  i > 0  repeat  i := i - count(fn, str)
  return i

ct5 has fn as a parameter.

As you can see ct3 is bad in all three Lisps, but how bad
depends on Lisp: on ecl it is "only" 5 time slower while
using sbcl it is almost 30.  Other versions are comparable,
with using explicit function instead of anonymous function
giving small saving.

> How to write a reliably fast program?

If you want fast programs use sbcl: currently on average
sbcl gives fastest code.  And as first step identify
bottlenecks.  sbcl has statistical profiler (I few times
wrote how to use it) which shows you which functions
take most of execution time.  Moreover, sbcl profiler
tells you who is responsible for calling given routine,
so you cat get form 'my program is spending too much
time allocating memory' to 'routine foo is causing
excessive memory allocation'.  Once you know
bottleneck you elliminate them, typically using cheaper
operations with equvalent effect.  In case of
excessive memory allocation making code more
imperative (reusing memory) may help a lot.

-- 
                              Waldek Hebisch
[email protected] 

-- 
You received this message because you are subscribed to the Google Groups 
"FriCAS - computer algebra system" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/fricas-devel?hl=en.

Reply via email to