unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* [PATCH] Improved string writing
@ 2005-04-20 12:46 Ludovic Courtès
  2005-04-20 21:45 ` Kevin Ryde
  0 siblings, 1 reply; 15+ messages in thread
From: Ludovic Courtès @ 2005-04-20 12:46 UTC (permalink / raw)


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))).


\f
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


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2005-06-09 17:50 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-04-20 12:46 [PATCH] Improved string writing Ludovic Courtès
2005-04-20 21:45 ` Kevin Ryde
2005-04-21  7:37   ` Ludovic Courtès
2005-04-21 22:10     ` Kevin Ryde
2005-04-21 22:26       ` Paul Jarc
2005-04-21 22:38         ` Kevin Ryde
2005-04-22  7:34           ` Ludovic Courtès
2005-04-29 23:43             ` Kevin Ryde
2005-05-02  7:37               ` Ludovic Courtès
2005-05-24 19:42           ` Marius Vollmer
2005-05-26 15:38             ` Ludovic Courtès
2005-06-06 19:30               ` Marius Vollmer
2005-06-06 19:51             ` Marius Vollmer
2005-06-07 11:33               ` Ludovic Courtès
2005-06-09 17:50                 ` Marius Vollmer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).