mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-09 21:40:33 +02:00
Speed up scm_c_write / scm_lfwrite
* libguile/ports-internal.h (scm_t_port): Add write_buf_aux field. * libguile/ports.h (scm_port_auxiliary_write_buffer): New internal decl. * libguile/ports.c (AUXILIARY_WRITE_BUFFER_SIZE): New constant. (initialize_port_buffers): Init aux write buf. (scm_port_auxiliary_write_buffer): Lazily allocate an aux write buffer. (scm_c_write): Arrange to write through an aux buffer if the port is unbuffered.
This commit is contained in:
parent
48dbadd8e6
commit
47918f38d9
3 changed files with 49 additions and 3 deletions
|
@ -312,6 +312,7 @@ struct scm_t_port
|
|||
/* Port buffers. */
|
||||
SCM read_buf;
|
||||
SCM write_buf;
|
||||
SCM write_buf_aux;
|
||||
|
||||
/* All ports have read and write buffers; an unbuffered port simply
|
||||
has a one-byte buffer. However unreading bytes can expand the read
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
#include "libguile/strings.h"
|
||||
#include "libguile/mallocs.h"
|
||||
#include "libguile/validate.h"
|
||||
//#include "libguile/ports.h"
|
||||
#include "libguile/ports.h"
|
||||
#include "libguile/ports-internal.h"
|
||||
#include "libguile/vectors.h"
|
||||
#include "libguile/weak-set.h"
|
||||
|
@ -109,6 +109,9 @@ static SCM sym_error;
|
|||
static SCM sym_substitute;
|
||||
static SCM sym_escape;
|
||||
|
||||
/* See scm_port_auxiliary_write_buffer and scm_c_write. */
|
||||
static const size_t AUXILIARY_WRITE_BUFFER_SIZE = 256;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -660,6 +663,7 @@ initialize_port_buffers (SCM port)
|
|||
pt->read_buffering = read_buf_size;
|
||||
pt->read_buf = make_port_buffer (port, read_buf_size);
|
||||
pt->write_buf = make_port_buffer (port, write_buf_size);
|
||||
pt->write_buf_aux = SCM_BOOL_F;
|
||||
}
|
||||
|
||||
SCM
|
||||
|
@ -2647,6 +2651,23 @@ SCM_DEFINE (scm_port_write_buffer, "port-write-buffer", 1, 0, 0,
|
|||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
SCM_DEFINE (scm_port_auxiliary_write_buffer, "port-auxiliary-write-buffer",
|
||||
1, 0, 0, (SCM port),
|
||||
"Return the auxiliary write buffer for a port.")
|
||||
#define FUNC_NAME s_scm_port_auxiliary_write_buffer
|
||||
{
|
||||
scm_t_port *pt;
|
||||
|
||||
SCM_VALIDATE_OPPORT (1, port);
|
||||
|
||||
pt = SCM_PORT (port);
|
||||
if (scm_is_false (pt->write_buf_aux))
|
||||
pt->write_buf_aux = make_port_buffer (port, AUXILIARY_WRITE_BUFFER_SIZE);
|
||||
|
||||
return pt->write_buf_aux;
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -2774,22 +2795,45 @@ scm_c_write (SCM port, const void *ptr, size_t size)
|
|||
scm_t_port *pt;
|
||||
SCM write_buf;
|
||||
size_t written = 0;
|
||||
int using_aux_buffer = 0;
|
||||
const scm_t_uint8 *src = ptr;
|
||||
|
||||
SCM_VALIDATE_OPOUTPORT (1, port);
|
||||
|
||||
pt = SCM_PORT (port);
|
||||
write_buf = pt->write_buf;
|
||||
|
||||
if (pt->rw_random)
|
||||
scm_end_input (port);
|
||||
|
||||
/* Imagine we are writing 40 bytes on an unbuffered port. If we were
|
||||
writing from a bytevector we could pass that write directly to the
|
||||
port. But since we aren't, we need to go through a bytevector, and
|
||||
if we went through the port buffer we'd have to make 40 individual
|
||||
calls to the write function. That would be terrible. Really we
|
||||
need an intermediate bytevector. But, we shouldn't use a trick
|
||||
analogous to what we do with expand-port-read-buffer!, because the
|
||||
way we use the cur and end cursors doesn't seem to facilitate that.
|
||||
So instead we buffer through an auxiliary write buffer if needed.
|
||||
To avoid re-allocating this buffer all the time, we store it on the
|
||||
port. It should never be left with buffered data.
|
||||
|
||||
Use of an auxiliary write buffer is triggered if the buffer is
|
||||
smaller than the size we would make for an auxiliary write buffer,
|
||||
and the write is bigger than the buffer. */
|
||||
write_buf = pt->write_buf;
|
||||
if (scm_port_buffer_size (write_buf) < size &&
|
||||
scm_port_buffer_size (write_buf) < AUXILIARY_WRITE_BUFFER_SIZE)
|
||||
{
|
||||
using_aux_buffer = 1;
|
||||
write_buf = scm_port_auxiliary_write_buffer (port);
|
||||
}
|
||||
|
||||
while (written < size)
|
||||
{
|
||||
size_t did_put = scm_port_buffer_put (write_buf, src, size - written);
|
||||
written += did_put;
|
||||
src += did_put;
|
||||
if (scm_port_buffer_can_put (write_buf) == 0)
|
||||
if (using_aux_buffer || scm_port_buffer_can_put (write_buf) == 0)
|
||||
scm_i_write (port, write_buf);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,6 +208,7 @@ SCM_INTERNAL SCM scm_port_read (SCM port);
|
|||
SCM_INTERNAL SCM scm_port_write (SCM port);
|
||||
SCM_INTERNAL SCM scm_port_read_buffer (SCM port);
|
||||
SCM_INTERNAL SCM scm_port_write_buffer (SCM port);
|
||||
SCM_INTERNAL SCM scm_port_auxiliary_write_buffer (SCM port);
|
||||
|
||||
/* Output. */
|
||||
SCM_API void scm_putc (char c, SCM port);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue