[GiNaC-list] regression in handling non-commutative objects [Was: new tinfo method makes is_a less efficient]

Sheplyakov Alexei varg at theor.jinr.ru
Tue Sep 11 20:15:43 CEST 2007


On Tue, Sep 11, 2007 at 05:07:58PM +0200, Diego Conti wrote:

> I have made some tests, and I think I may have found a more serious 
> (possibly unrelated) problem, i.e. version 1.4.0 appears to be 10 times 
> slower than 1.3.8!

I've reproduced this. Unfortunately, I have no idea what is the reason of
the slowdown.

$ cat reg.cpp

#include <ginac/ginac.h>
#include <ginac/version.h>
#include <iostream>

using namespace GiNaC;

#if GINACLIB_MINOR_VERSION == 3 
const unsigned TINFO_DifferentialOneForm =0x00200000U;
#endif

class DifferentialOneForm : public basic
{
    GINAC_DECLARE_REGISTERED_CLASS(DifferentialOneForm,basic);
    const int id;
public:   
    DifferentialOneForm(const int ID) : id(ID) { }
    unsigned return_type() const {return return_types::noncommutative;}
   
#if GINACLIB_MINOR_VERSION <= 3
    unsigned return_type_tinfo() const {return TINFO_DifferentialOneForm;}
#else
    tinfo_t return_type_tinfo() const {return &tinfo_static; }
#endif
   
    void do_print(const print_context & c, unsigned level) const
    {
        c.s<<"Alpha_"<<id;
    }
};


GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(DifferentialOneForm, basic,
		print_func<print_context>(&DifferentialOneForm::do_print))

void DifferentialOneForm::archive(archive_node & n) const { }
DifferentialOneForm::DifferentialOneForm(const archive_node & n, lst & sym_lst) : id(0) { }
ex DifferentialOneForm::unarchive(const archive_node & n, lst & sym_lst) { return 0; }

int DifferentialOneForm::compare_same_type(const basic & other) const
{
    const DifferentialOneForm& o=static_cast<const DifferentialOneForm&>(other);
    if (id<o.id)
			return -1;
    else if (id>o.id)
			return 1;
    else
			return 0;
}

DifferentialOneForm::DifferentialOneForm() : id(0)  { }

int main(int argc, char** argv)
{
	DifferentialOneForm u(1),v(2),w(3),s(4),t(5),r(6);
	symbol x,y,p;
	ex a=x*u*v+y*w*s+p*t*r;

	const size_t ntests=10000;
   
	for (size_t i=0; i<ntests; i++)
	  a*a*a;

	std::cout << a << std::endl;
	return 0;
}

$ g++ -I ginac-1.4 -o reg.1.4 reg.cpp -L./ginac-1.4/lib -lginac -Wl,--rpath=`pwd`/ginac-1.4/lib
$ g++ -I ginac-1.3 -o reg reg.cpp -L./ginac-1.3/lib -lginac -Wl,--rpath=`pwd`/ginac-1.3/lib
$ ldd ./reg | grep ginac | cut -d ' ' -f 1
        libginac-1.3.so.2
$ ldd ./reg.1.4 | grep ginac | cut -d ' ' -f 1
        libginac-1.4.so.0
$ time ./reg >/dev/null 2>&1

 real    0m0.064s
 user    0m0.064s
 sys     0m0.000s
$ time ./reg.1.4 >/dev/null 2>&1

real    0m0.690s
user    0m0.680s
sys     0m0.012s

I've made some interesting observations.

1.

The "old" (1.3.8) version gives stable result (i.e. it does not change from
run to run):

$ for i in `seq 1 50`; do ./reg; done | sort -n | uniq 
symbol3*(Alpha_5*Alpha_6)+symbol1*(Alpha_1*Alpha_2)+symbol2*(Alpha_3*Alpha_4)

With new one (1.4.0) result is not stable any more:

$ for i in `seq 1 50`; do ./reg.1.4 ; done | sort -n | uniq
(Alpha_1*Alpha_2)*symbol1+(Alpha_3*Alpha_4)*symbol2+(Alpha_5*Alpha_6)*symbol3
(Alpha_1*Alpha_2)*symbol1+(Alpha_3*Alpha_4)*symbol2+symbol3*(Alpha_5*Alpha_6)
(Alpha_1*Alpha_2)*symbol1+(Alpha_5*Alpha_6)*symbol3+symbol2*(Alpha_3*Alpha_4)
(Alpha_1*Alpha_2)*symbol1+symbol2*(Alpha_3*Alpha_4)+(Alpha_5*Alpha_6)*symbol3
(Alpha_3*Alpha_4)*symbol2+(Alpha_1*Alpha_2)*symbol1+(Alpha_5*Alpha_6)*symbol3
(Alpha_3*Alpha_4)*symbol2+(Alpha_1*Alpha_2)*symbol1+symbol3*(Alpha_5*Alpha_6)
(Alpha_3*Alpha_4)*symbol2+(Alpha_5*Alpha_6)*symbol3+(Alpha_1*Alpha_2)*symbol1
(Alpha_5*Alpha_6)*symbol3+(Alpha_1*Alpha_2)*symbol1+(Alpha_3*Alpha_4)*symbol2
(Alpha_5*Alpha_6)*symbol3+(Alpha_3*Alpha_4)*symbol2+(Alpha_1*Alpha_2)*symbol1
(Alpha_5*Alpha_6)*symbol3+symbol1*(Alpha_1*Alpha_2)+(Alpha_3*Alpha_4)*symbol2
(Alpha_5*Alpha_6)*symbol3+symbol1*(Alpha_1*Alpha_2)+symbol2*(Alpha_3*Alpha_4)
(Alpha_5*Alpha_6)*symbol3+symbol2*(Alpha_3*Alpha_4)+(Alpha_1*Alpha_2)*symbol1
symbol1*(Alpha_1*Alpha_2)+(Alpha_5*Alpha_6)*symbol3+symbol2*(Alpha_3*Alpha_4)
symbol1*(Alpha_1*Alpha_2)+symbol2*(Alpha_3*Alpha_4)+(Alpha_5*Alpha_6)*symbol3
symbol1*(Alpha_1*Alpha_2)+symbol2*(Alpha_3*Alpha_4)+symbol3*(Alpha_5*Alpha_6)
symbol1*(Alpha_1*Alpha_2)+symbol3*(Alpha_5*Alpha_6)+symbol2*(Alpha_3*Alpha_4)
symbol2*(Alpha_3*Alpha_4)+(Alpha_5*Alpha_6)*symbol3+symbol1*(Alpha_1*Alpha_2)
symbol2*(Alpha_3*Alpha_4)+symbol1*(Alpha_1*Alpha_2)+(Alpha_5*Alpha_6)*symbol3
symbol3*(Alpha_5*Alpha_6)+(Alpha_1*Alpha_2)*symbol1+(Alpha_3*Alpha_4)*symbol2
symbol3*(Alpha_5*Alpha_6)+(Alpha_3*Alpha_4)*symbol2+symbol1*(Alpha_1*Alpha_2)
symbol3*(Alpha_5*Alpha_6)+symbol1*(Alpha_1*Alpha_2)+symbol2*(Alpha_3*Alpha_4)
symbol3*(Alpha_5*Alpha_6)+symbol2*(Alpha_3*Alpha_4)+symbol1*(Alpha_1*Alpha_2)

2. 

This regression has something to do with handling non-commutative expressions
(e.g. there is no such slowdown with polynomials or rational functions).


Best regards,
 Alexei

-- 
All science is either physics or stamp collecting.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: Digital signature
Url : http://www.cebix.net/pipermail/ginac-list/attachments/20070911/8e293068/attachment.pgp


More information about the GiNaC-list mailing list