> < ^ Date: Mon, 05 Sep 1994 13:53:00 -0700 (PDT)
> < ^ From: Frank Celler <frank.celler@math.rwth-aachen.de >
> < ^ Subject: Re: a suggestion and a question

Dear Andrew,

Shouldn't gap have a runtime option, -rc say, which turns off
the automatic reading of the .gaprc file? I tend to put initialisation

yes, this would be handy.

A question on using AppendTo:
...
Any suggestions?

yes, there was a discussion about this subject in the GAP forum
earlier this year, I append the three relevant emails.

best wishes
Frank

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
From: Gap Students <studgap@twi.tudelft.nl>

Dear Gap Forum,

To be able to call an external executable, it's necessary to write
information to a file. As far as I know, GAP offers the functions
PrintTo and AppendTo. These functions both open a file, write the
information and close it again (am I right?) So when the function
AppendTo is used within a loop, writing in each cycle a small amount
of information, the file is opened and closed again very often,
consuming a huge amount of time.

Is there a way to open a file once, write all the information using
a loop, and close it again?

I have thought of using strings. First, all the information is stored
in a string (using Concatenation), after which the whole string is
written to a file using PrintTo. It turns out that, at least when
working under DOS, this is even slower than the first option.

Erik Roijackers / Gap Students

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
From: Steve Linton  <sl25@cus.cam.ac.uk>

To be able to call an external executable, it's necessary to write
information to a file. As far as I know, GAP offers the functions
PrintTo and AppendTo. These functions both open a file, write the
information and close it again (am I right?) So when the function
AppendTo is used within a loop, writing in each cycle a small amount
of information, the file is opened and closed again very often,
consuming a huge amount of time.

This is an especially bad problem under DOS, as UNIX gains the
benefit of disk caching.

Is there a way to open a file once, write all the information using
a loop, and close it again?

I don't believe so.
>
> I have thought of using strings. First, all the information is stored
> in a string (using Concatenation), after which the whole string is
> written to a file using PrintTo. It turns out that, at least when
> working under DOS, this is even slower than the first option.
>

Better is to put all the information into a GAP list and then write
it out in one go. If your external program can't handle the
resulting [] and ,s then you may have to write a little filter to
strip them out.

Another trick is to put the file on a RAM disk.

        Steve
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

From: Martin Schoenert <martin.schoenert@math.rwth-aachen.de>

Erik Roijackers writes in his e-mail message of 1994/03/23

To be able to call an external executable, it's necessary to write
information to a file. As far as I know, GAP offers the functions
PrintTo and AppendTo. These functions both open a file, write the
information and close it again (am I right?) So when the function
AppendTo is used within a loop, writing in each cycle a small amount
of information, the file is opened and closed again very often,
consuming a huge amount of time.

This is correct. It is just barely tolerable under UNIX. Under TOS (on
the Atari ST), it was impossible, because seeking to the end of the file
took time proportional to the size of a file. So writing a file with <n>
lines took time <n>^2. I don't now whether this is true under DOS.

He continues

Is there a way to open a file once, write all the information using
a loop, and close it again?

Hmm, yes and no. In C you open a file, obtain a file pointer, and then
use this to write to the file. Something like this is not possible in
GAP. That means you *cannot* write something like

file := OutputFile( "erwin" );
for i  in [1..100]  do
    PrintTo( file, Size( group[i] ), "\n" );
od;
CloseFile( file );

We plan something like this, but not for the immediate future.

But there is a hack, which may solve your problem. What you can do, is
to put your loop in a simple function. Then you call this function
from 'PrintTo'. I.e., do the following

Dummy := function ()
    for i  in [1..100]  do
        Print( Size( group[i] ), "\n" );
    od;
end;
PrintTo( "erwin", Dummy() );

This makes use of the fact that when the arguments to 'PrintTo' are
evaluated the current output file is the one opened by 'PrintTo', so
everything that would usually go to '*stdout*' (i.e., the screen) is
written to the file.

This doesn't solve all problems, because you cannot interact with GAP
while the output is computed and written to the file, but in many cases
this is sufficient.

He continues

I have thought of using strings. First, all the information is stored
in a string (using Concatenation), after which the whole string is
written to a file using PrintTo. It turns out that, at least when
working under DOS, this is even slower than the first option.

In GAP 3.3 'Concatenation' has a ``small'' problem. It creates the
output list as a list of characters (with each character taking 4 bytes)
instead of as a string. So the reason why this is slower is probably
because the string becomes so large that GAP has to do many garbage
collections.

You might want to try something like the following code.

cache := "";
for i  in [1..100]  do
    Append( cache, String( Size( group[i] ) ), "\n" );
    if 8192 < Length(cache)  then
        AppendTo( "erwin", cache );
        cache := "";
    fi;
od;

Hope this helps, Martin.


> < [top]