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 _______________________________________________ Guile-user mailing list Guile-user@gnu.org http://lists.gnu.org/mailman/listinfo/guile-user