From: k p c
Subject: How to speed up DECODE-UNIVERSAL-TIME?  How to save last 4 results?
Date: 
Message-ID: <1996Feb7.050659.26205@ptolemy-ethernet.arc.nasa.gov>
DECODE-UNIVERSAL-TIME, ENCODE-UNIVERSAL-TIME, and functions like
TRUNCATE called by them use perhaps 75% of an application's CPU time
in Allegro 4.2.

I ran an analysis and found that decode-universal-time is improved by
saving the last set of returned multiple values.  I did this manually
and found an improvement, but it probably needs to have the last 4
sets of results saved.  Not a hash table, but the last 4 only, as it
is called millions of times and I don't want to grow a hash table.

And there's the problem.  What data structure to store 4 sets of
multiple values in?  How exactly to declare it?  What is fastest?

And, in general, how best to speed those two functions up?  I almost
certainly don't want to rewrite my large time arithmetic package to
use a different representation (days since the year 1 or whatever), as
it is quite powerful and trustworthy for my needs and I don't know of
anything else in CL that does anything comparable.  I just want it to
be faster.

I have already tried declaring everything in sight to their possihle
values.  Also, I have sped up ancillary calculations by using number
of seconds since 1995, a fixnum, but there seems to be a sort of
fixnum to bignum contagion that Allegro seems to presume unless you
tell it that all fixnums are always fixnums, and I'm not sure I want
to go into nonportable declarations.  Another salient point is that I
could double the speed of everything by using algorithms that ignore
daylight savings time, but that is not an option, unfortunately.

If you post a followup to this article, I would appreciate a courtesy
verbatim copy by email to help work around potentially unreliable feeds.

---
···@ptolemy.arc.nasa.gov.  AI, multidisciplinary neuroethology, info filtering.
The other side of the free speech coin is freedom from fear of listening; what
use if nobody may dare listen?  Privacy, web and net, preserves democracy thus.

From: Ken Anderson
Subject: Re: How to speed up DECODE-UNIVERSAL-TIME?  How to save last 4 results?
Date: 
Message-ID: <KANDERSO.96Feb12094242@stout.bbn.com>
In article <·····················@ptolemy-ethernet.arc.nasa.gov> k p c <···@ptolemy.arc.nasa.gov> writes:
  ...
  I have already tried declaring everything in sight to their possihle
  values.  Also, I have sped up ancillary calculations by using number
  of seconds since 1995, a fixnum, but there seems to be a sort of
  fixnum to bignum contagion that Allegro seems to presume unless you
  tell it that all fixnums are always fixnums, and I'm not sure I want
  to go into nonportable declarations.  Another salient point is that I
  could double the speed of everything by using algorithms that ignore
  daylight savings time, but that is not an option, unfortunately.
  
If you send me the code you are using, perhaps i can be more helpful.  I
don't understand what you are asking about the 4 sets of multiple values.

However, when using fixnum operations, it is important to declare both the
arguments and the result to be fixnums.  This is because fixnum arguments
can produce bignum results which Lisp must check for.
From: Kelly Murray
Subject: Re: How to speed up DECODE-UNIVERSAL-TIME?  How to save last 4 results?
Date: 
Message-ID: <4foure$ot@sparky.franz.com>
>> I ran an analysis and found that decode-universal-time is improved by
>> saving the last set of returned multiple values.  I did this manually
>> and found an improvement, but it probably needs to have the last 4
>> sets of results saved.  Not a hash table, but the last 4 only, as it
>> is called millions of times and I don't want to grow a hash table.
>> 

Here is a general constructor for caching the results of a function call: 
You should add code to reset the use-counter to keep it a fixnum, and
make sure the initial values in the arg-cache never match the input. 

Replace calls to your-name-here  to caching-your-name-here in your
source code and then do:

(setf (symbol-function 'caching-your-name-here) 
      (caching-one-arg-call #'your-name-here 4))

(defun caching-one-arg-call (function cache-size)
  (let ((arg-cache (make-array cache-size))
        (val-cache (make-array cache-size))
        (use-cache (make-array cache-size :initial-element 0))
        (use-counter 0)
	)
    #'(lambda (arg) 
        (let ((index (position arg arg-cache))
	      (values nil))
          (cond
	   (index
	    (unless (eq (aref use-cache index) use-counter)
	       (setf (aref use-cache index) (incf use-counter)))
	    (values-list (aref val-cache index)))
	   (t
	    (setf values (multiple-value-list (funcall function arg)))
	    (setf index 0)
	    (dotimes (i cache-size)
	      (if (< (aref use-cache i) (aref use-cache index))
		  (setf index i)))
	    (setf (aref use-cache index) (incf use-counter))
	    (setf (aref arg-cache index) arg)
	    (setf (aref val-cache index) values)
	    (values-list values)))
	  ))))
	  
-Kelly Murray   ···@franz.com    http://www.franz.com
	    
	      
	    
 
From: HStearns
Subject: Re: How to speed up DECODE-UNIVERSAL-TIME?  How to save last 4 results?
Date: 
Message-ID: <4g5kd8$7iu@newsbf02.news.aol.com>
     Subject: How to speed up DECODE-UNIVERSAL-TIME?  How to save last 4
results?
     From: k p c <···@ptolemy.arc.nasa.gov>
     Date: Wed, 7 Feb 1996 05:14:41 GMT
     Message-ID: <·····················@ptolemy-ethernet.arc.nasa.gov>

     DECODE-UNIVERSAL-TIME, ENCODE-UNIVERSAL-TIME, and functions like
     TRUNCATE called by them use perhaps 75% of an application's CPU time
     in Allegro 4.2.

     I ran an analysis and found that decode-universal-time is improved by
     saving the last set of returned multiple values.  I did this manually
     and found an improvement, but it probably needs to have the last 4
     sets of results saved.  Not a hash table, but the last 4 only, as it
     is called millions of times and I don't want to grow a hash table.

     And there's the problem.  What data structure to store 4 sets of
     multiple values in?  How exactly to declare it?  What is fastest?

     And, in general, how best to speed those two functions up?  I almost
     certainly don't want to rewrite my large time arithmetic package to
     use a different representation (days since the year 1 or whatever),
as
     it is quite powerful and trustworthy for my needs and I don't know of
     anything else in CL that does anything comparable.  I just want it to
     be faster.

     I have already tried declaring everything in sight to their possihle
     values.  Also, I have sped up ancillary calculations by using number
     of seconds since 1995, a fixnum, but there seems to be a sort of
     fixnum to bignum contagion that Allegro seems to presume unless you
     tell it that all fixnums are always fixnums, and I'm not sure I want
     to go into nonportable declarations.  Another salient point is that I
     could double the speed of everything by using algorithms that ignore
     daylight savings time, but that is not an option, unfortunately.

     If you post a followup to this article, I would appreciate a courtesy
     verbatim copy by email to help work around potentially unreliable
feeds.

     ---
     ···@ptolemy.arc.nasa.gov.  AI, multidisciplinary neuroethology, info
filtering.
     The other side of the free speech coin is freedom from fear of
listening; what
     use if nobody may dare listen?  Privacy, web and net, preserves
democracy thus.

Although most good compilers can use declarations to improve the speed
of fixnum arithmetic, most are not able to do much with:

  - integer declarations - Some Lisps don't respond well to
declarations like (integer 0 <some-reasonble-size>), only with fixnum.
For several time values, fixnums don't cut it. 

  - declarations for function returning multiple values

Unless Franz has some clues, you might try writing your own C
functions and then calling them using the foreign function interface.