[comp.unix.questions] C/UNIX low level I/O

david@pyr.gatech.EDU (David Brown) (11/02/88)

 Hi, NetLanders.  I've a small C/UNIX problem.  I need to do a bunch of
 small write's to a file.  I need to know the quickest way to do it.
 I've got a linked list of 'words' that I need written to a file in a 
 humanly readable and understandable fashion.  But it needs to take as
 little time as possible.  For instance, the way I have it now, I use
 write(2).  But this ay, I do a separate 'write' for every word in the
 list, and a 'write' for the spaces between and the newlines. Like this:
 
        while (list ~empty){
         write word
         write space
        }
        write newline

 My question: is there a better way to do this?  I've thought of using 
 higher-level I/O routines like fprintf, but I think they would be
 less efficient. But less efficient than what I'm doing now?

Thanks,
 David Brown

----------------------------------------------------------------------------
David Brown
Armstrong State College, Savannah, Georgia
uucp: ...!{akgua,allegra,amd,hplabs,uunet,seismo,ut-ngp}!gatech!gitpyr!david
ARPA: david@pyr.gatech.edu

crossgl@ingr.UUCP (Gordon Cross) (11/02/88)

In article <6695@pyr.gatech.EDU>, david@pyr.gatech.EDU (David Brown) writes:
> 
>  Hi, NetLanders.  I've a small C/UNIX problem.  I need to do a bunch of
>  small write's to a file.  I need to know the quickest way to do it.
>  I've got a linked list of 'words' that I need written to a file in a 
>  humanly readable and understandable fashion.  But it needs to take as
>  little time as possible.  For instance, the way I have it now, I use
>  write(2).  But this ay, I do a separate 'write' for every word in the
>  list, and a 'write' for the spaces between and the newlines.

I've had some experience doing a similiar thing myself.  I acheived a
significant increase in throughput by filling a memory buffer with the image
of the data I wished to write out and then doing a single write(2) for the
whole buffer.  The reason this is faster is that each call to write(2) requires
a process context switch to the kernal to service the request.  The disk
controller itself can slow you down if it is called on repeatedly to do small
operations.  I could rant on and on about why this is the case but you should
have the general idea.  Also your buffer should be at least the size of a 
disk block or multiple thereof.  Good luck!


Gordon Cross
Intergraph Corp.  Huntsville, AL

jds@mimsy.UUCP (James da Silva) (11/03/88)

In article <6695@pyr.gatech.EDU> david@pyr.gatech.edu (David Brown) writes:
>
> ...  But this ay, I do a separate 'write' for every word in the
> list, and a 'write' for the spaces between and the newlines. Like this:
> 
[ pseudocode showing writes for each word and space, then for the newline ]
>
> My question: is there a better way to do this?  I've thought of using 
> higher-level I/O routines like fprintf, but I think they would be
> less efficient. But less efficient than what I'm doing now?

If you don't need the formatting capabilities of fprintf, try using fputs.
I think you will see a significant speed boost because the stdio library
buffers your output rather than doing a system call for each word.

You can get even more juice by buffering it yourself, since you don't have
to be as general as stdio does.  But then you have to be sure to pick a 
good buffer size for your system...

					- Jaime

----------------------------------------------------------------------
path:   uunet!mimsy!jds 				James da Silva
domain: jds@mimsy.umd.edu

rob@pbhyf.PacBell.COM (Rob Bernardo) (11/03/88)

In article <6695@pyr.gatech.EDU> david@pyr.gatech.edu (David Brown) writes:
+   I need to do a bunch of
+ small write's to a file.  I need to know the quickest way to do it.
...
+   For instance, the way I have it now, I use
+ write(2).  But this ay, I do a separate 'write' for every word in the
+ list, and a 'write' for the spaces between and the newlines. Like this:
+ 
+        while (list ~empty){
+         write word
+         write space
+        }
+        write newline
+
+ My question: is there a better way to do this?  I've thought of using 
+ higher-level I/O routines like fprintf, but I think they would be
+ less efficient. But less efficient than what I'm doing now?

Use fputs() to write the strings (your "word") and fputc() to write the
single characters (your "space" and "newline"). Fprintf() is overkill
because you don't have any formatting of the output to perform. Using
these stdio functions instead of the system call write() is more
efficient insofar as these functions buffer the writes, i.e. generally
they store what is to be written until a whole block is to be written, and
then they call write() to  write whole blocks at a time. (WARNING: that's
a simplification.)
-- 
Rob Bernardo, Pacific Bell UNIX/C Reusable Code Library
Email:     ...![backbone]!pacbell!pbhyf!rob   OR  rob@pbhyf.PacBell.COM
Office:    (415) 823-2417  Room 4E750A, San Ramon Valley Administrative Center
Residence: (415) 827-4301  R Bar JB, Concord, California

gwyn@smoke.BRL.MIL (Doug Gwyn ) (11/03/88)

In article <6695@pyr.gatech.EDU> david@pyr.gatech.edu (David Brown) writes:
> My question: is there a better way to do this?  I've thought of using 
> higher-level I/O routines like fprintf, but I think they would be
> less efficient. But less efficient than what I'm doing now?

fputs() and fprintf() will undoubtedly be significantly faster than
write(), and more portable besides.

mr@homxb.UUCP (mark) (11/03/88)

In article <6695@pyr.gatech.EDU>, david@pyr.gatech.EDU (David Brown) writes:
# 
#  Hi, NetLanders.  I've a small C/UNIX problem.  I need to do a bunch of
#  small write's to a file.  I need to know the quickest way to do it.
#  I've got a linked list of 'words' that I need written to a file in a 
#  humanly readable and understandable fashion.  But it needs to take as
#  little time as possible.  For instance, the way I have it now, I use
#  write(2).  But this ay, I do a separate 'write' for every word in the
#  list, and a 'write' for the spaces between and the newlines. Like this:
#  
#         while (list ~empty){
#          write word
#          write space
#         }
#         write newline
# 
#  My question: is there a better way to do this?  I've thought of using 
#  higher-level I/O routines like fprintf, but I think they would be
#  less efficient. But less efficient than what I'm doing now?

You could make a buffer, say 512 chars. Fill the buffer and then
'write' the entire buffer out. (as long as this is not an interactive
application). If you want you can use 'sprintf(3)' to compile a
string which would then be attached to the buffer with strcat or
your own routine.

# Thanks,
#  David Brown

mark
homxb!mr