[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Improved string writing
From: |
Ludovic Courtès |
Subject: |
[PATCH] Improved string writing |
Date: |
Wed, 20 Apr 2005 14:46:52 +0200 |
User-agent: |
Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux) |
Hi,
While running Guile 1.7.2 under `strace', I noticed the following
unpleasant thing:
write(1, "\"", 1) = 1
write(1, "h", 1) = 1
write(1, "e", 1) = 1
write(1, "l", 1) = 1
write(1, "l", 1) = 1
write(1, "o", 1) = 1
write(1, "\"", 1) = 1
All these system calls for just writing the string "hello". :-)
The patch below adds buffering in `iprin1' (print.c) so that regular
strings (i.e. strings that don't contain any special characters) can be
written with only one `write' system call, while other strings[*] may be
printed with only a few `write' system calls.
Note that `format' in (ice-9 format) uses `write-char', which
unfortunately leads to the same problem as above. So this will have to
be fixed eventually too.
Please, let me know if the patch looks ok.
Thanks,
Ludovic.
[*] Test case: (list->string (map integer->char (iota 40))).
diff -ubB --show-c-function /home/ludo/tmp/guile-1.7.2/libguile/print.c\~
/home/ludo/tmp/guile-1.7.2/libguile/print.c
--- /home/ludo/tmp/guile-1.7.2/libguile/print.c~ 2005-03-03
23:12:33.000000000 +0100
+++ /home/ludo/tmp/guile-1.7.2/libguile/print.c 2005-04-20 14:09:14.000000000
+0200
@@ -508,29 +508,57 @@ iprin1 (SCM exp, SCM port, scm_print_sta
{
size_t i, len;
const char *data;
+ char *buffer;
+ size_t buffer_len, buffer_pos = 0;;
- scm_putc ('"', port);
len = scm_i_string_length (exp);
data = scm_i_string_chars (exp);
+
+ /* Allocate a string buffer large enough for the common case of
+ a printable string. */
+ buffer = alloca (len + 20);
+ buffer_len = len + 20;
+
+#define PUSH_TO_BUFFER(_chr) \
+ do \
+ { \
+ if (buffer_pos + 1 > buffer_len) \
+ { \
+ /* Flush BUFFER to PORT. */ \
+ scm_lfwrite (buffer, buffer_len, port); \
+ buffer_pos = 0; \
+ } \
+ \
+ buffer[buffer_pos++] = (_chr); \
+ } \
+ while (0)
+
+ PUSH_TO_BUFFER ('"');
for (i = 0; i < len; ++i)
{
unsigned char ch = data[i];
if ((ch < 32 && ch != '\n') || (127 <= ch && ch < 148))
{
static char const hex[]="0123456789abcdef";
- scm_putc ('\\', port);
- scm_putc ('x', port);
- scm_putc (hex [ch / 16], port);
- scm_putc (hex [ch % 16], port);
+ PUSH_TO_BUFFER ('\\');
+ PUSH_TO_BUFFER ('x');
+ PUSH_TO_BUFFER (hex [ch / 16]);
+ PUSH_TO_BUFFER (hex [ch % 16]);
}
else
{
if (ch == '"' || ch == '\\')
- scm_putc ('\\', port);
- scm_putc (ch, port);
+ PUSH_TO_BUFFER ('\\');
+ PUSH_TO_BUFFER (ch);
}
}
- scm_putc ('"', port);
+ PUSH_TO_BUFFER ('"');
+
+ if (buffer_pos > 0)
+ /* Flush BUFFER to PORT up to BUFFER_POS. */
+ scm_lfwrite (buffer, buffer_pos, port);
+
+#undef PUSH_TO_BUFFER
scm_remember_upto_here_1 (exp);
}
else
- [PATCH] Improved string writing,
Ludovic Courtès <=