login  home  contents  what's new  discussion  bug reports     help  links  subscribe  changes  refresh  edit

Adding new functions to PrimitiveArray? in an attempt to improve performance.

new(n,x:NNI->S)
create new array of size n with values from x(i),i=0..n-1
fill!(n,x:NNI->S)
set the elements of array with values from x(i),i=0..n-1

This is the code for Axiom's PrimitiveArray? domain with two small changes for options to call new and fill! with an initialization function rather than just a constant.

fricas
(1) -> <spad>
fricas
)abbrev domain XPRIMARR XPrimitiveArray
NNI ==> NonNegativeInteger
-- This provides a fast array type with no bound checking on elt's.
-- Minimum index is 0 in this type, cannot be changed
XPrimitiveArray(S:Type): OneDimensionalArrayAggregate S with
     new:(NNI,NNI->S)->%
     fill!:(%,NNI->S)->%
  == add
   Qmax ==> QVMAXINDEX$Lisp
   Qsize ==> QVSIZE$Lisp
   Qelt ==> QAREF1$Lisp
   Qsetelt ==> QSETAREF1$Lisp
   Qnew ==> MAKE_-ARRAY$Lisp
   Qnew1 ==> MAKEARR1$Lisp
#x == Qsize x minIndex x == 0 empty() == Qnew(0$Lisp) new(n:NNI, x:S):% == Qnew1(n, x) new(n:NNI, x:NNI->S):% == fill!(Qnew n, x) qelt(x, i) == Qelt(x, i) elt(x:%, i:Integer) == Qelt(x, i) qsetelt!(x, i, s) == Qsetelt(x, i, s) setelt(x:%, i:Integer, s:S) == Qsetelt(x, i, s) fill!(x:%, s:S):% == (for i in 0..Qmax x repeat Qsetelt(x, i, s); x) fill!(x:%, s:NNI->S):% == (for i in 0..Qmax x repeat Qsetelt(x, i, s(i)); x)</spad>
fricas
Compiling FriCAS source code from file 
      /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/7411497222316612988-25px001.spad
      using old system compiler.
   XPRIMARR abbreviates domain XPrimitiveArray 
------------------------------------------------------------------------
   initializing NRLIB XPRIMARR for XPrimitiveArray 
   compiling into NRLIB XPRIMARR 
   processing macro definition Qmax ==> Sel(Lisp,QVMAXINDEX) 
   processing macro definition Qsize ==> Sel(Lisp,QVSIZE) 
   processing macro definition Qelt ==> Sel(Lisp,QAREF1) 
   processing macro definition Qsetelt ==> Sel(Lisp,QSETAREF1) 
   processing macro definition Qnew ==> Sel(Lisp,MAKE-ARRAY) 
   processing macro definition Qnew1 ==> Sel(Lisp,MAKEARR1) 
   compiling exported # : % -> NonNegativeInteger
      XPRIMARR;#;%Nni;1 is replaced by QVSIZE 
Time: 0 SEC.
compiling exported minIndex : % -> Integer XPRIMARR;minIndex;%I;2 is replaced by 0 Time: 0 SEC.
compiling exported empty : () -> % XPRIMARR;empty;%;3 is replaced by MAKE-ARRAY0 Time: 0 SEC.
compiling exported new : (NonNegativeInteger,S) -> % XPRIMARR;new;NniS%;4 is replaced by MAKEARR1 Time: 0 SEC.
compiling exported new : (NonNegativeInteger,NonNegativeInteger -> S) -> % Time: 0 SEC.
compiling exported qelt : (%,Integer) -> S XPRIMARR;qelt;%IS;6 is replaced by QAREF1 Time: 0 SEC.
compiling exported elt : (%,Integer) -> S XPRIMARR;elt;%IS;7 is replaced by QAREF1 Time: 0 SEC.
compiling exported qsetelt! : (%,Integer,S) -> S XPRIMARR;qsetelt!;%I2S;8 is replaced by QSETAREF1 Time: 0 SEC.
************* USER ERROR ********** available signatures for setelt: NONE NEED setelt: (%,(|Integer|),S) -> ? ****** comp fails at level 3 with expression: ****** (DEF (|setelt| |x| |i| |s|) (NIL % (|Integer|) S) ((|Sel| |Lisp| QSETAREF1) |x| |i| |s|)) ****** level 3 ****** $x:= (DEF (setelt x i s) (NIL NIL NIL NIL) ((Sel Lisp QSETAREF1) x i s)) $m:= $EmptyMode $f:= ((((|s| #) (|i| #) (* #) (+ #) ...)))
>> Apparent user error: unspecified error

How long does this take?

First, it seems to make a big difference whether the initialization is done by an anonymous function or by a named function since the latter can be compiled and called with very little overhead. In other words using:

  init1(x:Integer):Integer == random(100)-random(100)

is much better than this:

fricas
)time on
l0:PRIMARR(INT):=new(100000,0); map!(x+->random(100)-random(100),l0);
Type: PrimitiveArray?(Integer)
fricas
Time: 0.01 sec

Old way using a compiled initialization function with the map! function:

fricas
init1(x:Integer):Integer == random(100)-random(100)
Function declaration init1 : Integer -> Integer has been added to workspace.
Type: Void
fricas
Time: 0 sec
l1:PRIMARR(INT):=new(100000,0); map!(init1,l1);
fricas
Compiling function init1 with type Integer -> Integer
Type: PrimitiveArray?(Integer)
fricas
Time: 0 sec

New way with the call to the initialization function builtin to the new function:

fricas
init2(x:NNI):Integer == random(100)-random(100)
Function declaration init2 : NonNegativeInteger -> Integer has been added to workspace.
Type: Void
fricas
Time: 0 sec
l2:XPRIMARR(INT):=new(100000,init2);
XPrimitiveArray is an unknown constructor and so is unavailable. Did you mean to use -> but type something different instead?

Show the first few entries

fricas
for i in 0..10 repeat output [l0.i,l1.i,l2.i]
There are no library operations named l2 Use HyperDoc Browse or issue )what op l2 to learn if there is any operation containing " l2 " in its name. Cannot find a definition or applicable library operation named l2 with argument type(s) NonNegativeInteger
Perhaps you should use "@" to indicate the required return type, or "$" to specify which version of the function you need. FriCAS will attempt to step through and interpret the code. There are no library operations named l2 Use HyperDoc Browse or issue )what op l2 to learn if there is any operation containing " l2 " in its name.
Cannot find a definition or applicable library operation named l2 with argument type(s) NonNegativeInteger
Perhaps you should use "@" to indicate the required return type, or "$" to specify which version of the function you need.




  Subject:   Be Bold !!
  ( 15 subscribers )  
Please rate this page: