Your code looks ok to me.

Dunno about rulecheck clause, to make Robert Dodier happy?

I don't know why GCL is slow but looking around, here are some thoughts on

speeding stuff up more. I hope you or someone has the time

1. do this:

(setf (get 'mlist 'msimpind) '(mlist simp))

What this does is it uses the same list structure all the time for (mlist simp) in the header of the

list after simplification, instead of consing up 10^4 redundant lists.

2. (and this is in general to potentially speed up maxima' simplifier all over the place...)

This hack was put in the pre-dump-the-binary phase in an attempt to speed things up, but maybe in

the effort to use non-lisp for such things, got lost(?)

Anyway, it is to put the property list of operators in an order in which the most time-critical

ones come first.

Rationale: if you are running the simplifier and encounter the operator %sin, in order

to simplify it, you look on the property list of %sin for the place where the simplifier

program is stored. It is stored under the property operators. That is, you do

(get '%sin 'operators) and you get the symbol SIMP-%SIN.

(a) you would hope that this property, used most often, would be at the front of the plist

so as to make access fast.

It is not. It is in position 22, so that 44 memory references are needed to get to the simplifier

function. Because other stuff was (uh) pushed on the plist later. What time-critical stuff

might that be? well, wxmaxima display properties, tex display properties, integration properties,

file source-code data etc. So a simple program to go through all the operators in Maxima and rearrange the

symbol-plists so that the operators property comes first, could save time, and would use

no more storage.

Even the heavily-used operators have this lag built in. to find the operators property of MPLUS

requires 32 memory references.

(b) Yet another level of memory reference could be removed. This way:

SIMP-%SIN is an atom. It is not actually the lisp function. To get that, we can compute

(symbol-function 'simp-%sin) and we get something that is essentially a machine address, though

how it is printed varies with the lisp system. On GCL I get #<compiled-function SIMP-%SIN>

Also it would pay to move msimpind near to the front of the plists.

So here's thelisp program...

`;; move property to front of property list`

`(in-package :maxima)`

`(defun motf(r p) ; r is symbol, p is property`

` (let ((q (get r p)))`

` (cond (q (remf (symbol-plist r)p )`

` (setf (get r p) q) ;; put it back`

` q)`

` (t 'not_found))))`

`(defun $speedup(r)`

` (motf r 'msimpind)`

` (motf r 'operators))`

..........

in maxima , how to use it?

map (speedup, [?mplus, ?mtimes, ?mexpt, sin,cos, tan, nounify(integrate)])

note: the nounify(integrate) is necessary because the integration facility has mixed up evaluation and

simplification...

So here's what you can do:

run this speedup, once. and see if it makes your favorite timing benchmark run faster. It should

make simplification faster. Whether you notice it or not depends on how much other serious

computing is going on.

If you like it, the people who make binaries should

(a) make a list of all the common operators and run speedup on them, just before the system is dumped.

After wxmaxima or whatever has been loaded.

(b) then dump the system.

On 3/29/2014 4:45 AM, Barton Willis wrote:

Dunno about rulecheck clause, to make Robert Dodier happy?

I don't know why GCL is slow but looking around, here are some thoughts on

speeding stuff up more. I hope you or someone has the time

1. do this:

(setf (get 'mlist 'msimpind) '(mlist simp))

What this does is it uses the same list structure all the time for (mlist simp) in the header of the

list after simplification, instead of consing up 10^4 redundant lists.

2. (and this is in general to potentially speed up maxima' simplifier all over the place...)

This hack was put in the pre-dump-the-binary phase in an attempt to speed things up, but maybe in

the effort to use non-lisp for such things, got lost(?)

Anyway, it is to put the property list of operators in an order in which the most time-critical

ones come first.

Rationale: if you are running the simplifier and encounter the operator %sin, in order

to simplify it, you look on the property list of %sin for the place where the simplifier

program is stored. It is stored under the property operators. That is, you do

(get '%sin 'operators) and you get the symbol SIMP-%SIN.

(a) you would hope that this property, used most often, would be at the front of the plist

so as to make access fast.

It is not. It is in position 22, so that 44 memory references are needed to get to the simplifier

function. Because other stuff was (uh) pushed on the plist later. What time-critical stuff

might that be? well, wxmaxima display properties, tex display properties, integration properties,

file source-code data etc. So a simple program to go through all the operators in Maxima and rearrange the

symbol-plists so that the operators property comes first, could save time, and would use

no more storage.

Even the heavily-used operators have this lag built in. to find the operators property of MPLUS

requires 32 memory references.

(b) Yet another level of memory reference could be removed. This way:

SIMP-%SIN is an atom. It is not actually the lisp function. To get that, we can compute

(symbol-function 'simp-%sin) and we get something that is essentially a machine address, though

how it is printed varies with the lisp system. On GCL I get #<compiled-function SIMP-%SIN>

Also it would pay to move msimpind near to the front of the plists.

So here's thelisp program...

..........

in maxima , how to use it?

map (speedup, [?mplus, ?mtimes, ?mexpt, sin,cos, tan, nounify(integrate)])

note: the nounify(integrate) is necessary because the integration facility has mixed up evaluation and

simplification...

So here's what you can do:

run this speedup, once. and see if it makes your favorite timing benchmark run faster. It should

make simplification faster. Whether you notice it or not depends on how much other serious

computing is going on.

If you like it, the people who make binaries should

(a) make a list of all the common operators and run speedup on them, just before the system is dumped.

After wxmaxima or whatever has been loaded.

(b) then dump the system.

On 3/29/2014 4:45 AM, Barton Willis wrote:

The standard pop and push (defined in basic) are especially slow using Maxima compiled with GCL.

For N = 5*10^4, run times for (l : [], for i : 1 thru N do push(x,l), for i : 1 thru N do pop(l)) are

CCL 7.0500 seconds

GCL 73.8600 seconds

For either GCL or CCL, my pop and push run the test OK

CCL 0.6390 seconds

GCL 0.52 seconds

For tellsimp rules on lists, there are plenty of restrictions--I don't think that a tellsimp rule on a list

could, for example, sort the list.

--Barton

(defmspec $push (z)

(let* ((o (car (pop z)))

(x (if z (pop z) (wna-err o)))

(l (if z (pop z) (wna-err o)))

(ll (meval l)))

(if z (wna-err o))

(if (and ($mapatom l) ($listp ll))

(progn

(setq ll (cons (meval x) (cdr ll)))

;;alternative: (mset l (if (rulechk 'mlist) (simplifya (cons '(mlist) ll) t) (cons '(mlist simp) ll))))

(mset l (simplifya (cons '(mlist) ll) t)))

(merror "Second argument to push must be a mapatom that is bound to a list"))))

(defmspec $pop (z)

(let* ((o (car (pop z)))

(l (if z (pop z) (wna-err o)))

(ll (meval l)))

(if z (wna-err o))

(cond ((and ($mapatom l) ($listp ll))

(if ($emptyp ll) (merror "Pop called on an empty list")

(prog2

(setq ll (cdr ll))

(pop ll)

;; alternative: (mset l (if (rulechk 'mlist) (simplifya (cons '(mlist) ll) t) (cons (list 'mlist 'simp) ll))))))

(mset l (simplifya (cons '(mlist) ll) t)))))

(t (merror "Argument to pop must be a mapatom that is bound to a list")))))

And some tests

errcatch(push());

[]$

errcatch(push(2014));

[]$

errcatch(push(a,b,c));

[]$

errcatch(push(a,[1,2]));

[]$

errcatch(pop());

[]$

errcatch(pop(2014));

[]$

errcatch(pop([1,2]));

[]$

(l : [1,2],0);

0$

errcatch(pop(l,12));

[]$

errcatch(push(x,l, 2014));

[]$

(l : [1,2], push(x,l),l);

[x,1,2]$

[pop(l), l];

[x, [1,2]]$

(l : [false], [pop(l), l]);

[false,[]]$

(l : [1,2], a : push(0,l), pop(l), [a,l]);

[[0,1,2],[1,2]]$

(l : [1,2], push(l,l));

[[1,2],1,2]$

(remvalue(a), a[%pi] : [0,1,[8]], 0);

0$

(push(2014, a[%pi]), a[%pi]);

[2014,0,1,[8]]$

(pop(a[%pi]), a[%pi]);

[0,1,[8]]$

(l1 : [0], l2 : [0,1], l3 : [0,1,2],0);

0$

map('pop, '[l1,l2,l3]);

[0,0,0]$

[l1,l2,l3];

[[],[1],[1,2]]$

(a : b, b : c, c : d, d : e, e : f,0);

0$

(l : [a,b,c,d,e], push(x,l), pop(l),l);

[b,c,d,e,f]$

[pop(l),pop(l),pop(l),pop(l),pop(l)];

[b,c,d,e,f]$

(remvalue(a,l,l1,l2,l3,b,c,d,e,f),remarray(a), 0);

0$

------------------------------------------------------------------------------

_______________________________________________ Maxima-discuss mailing list Maxima-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/maxima-discuss