From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: ludo@gnu.org (Ludovic =?iso-8859-1?Q?Court=E8s?=) Newsgroups: gmane.lisp.guile.devel Subject: Inlining `scm_getc ()' and friends Date: Mon, 14 Apr 2008 18:28:24 +0200 Message-ID: <87iqyk9z9z.fsf@gnu.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: ger.gmane.org 1208191244 11265 80.91.229.12 (14 Apr 2008 16:40:44 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 14 Apr 2008 16:40:44 +0000 (UTC) To: guile-devel@gnu.org Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Mon Apr 14 18:41:13 2008 connect(): Connection refused Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1JlRYi-00026j-Oq for guile-devel@m.gmane.org; Mon, 14 Apr 2008 18:29:33 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JlRY4-0001jX-I1 for guile-devel@m.gmane.org; Mon, 14 Apr 2008 12:28:52 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JlRXt-0001g7-Nl for guile-devel@gnu.org; Mon, 14 Apr 2008 12:28:41 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JlRXs-0001az-0M for guile-devel@gnu.org; Mon, 14 Apr 2008 12:28:40 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JlRXq-0001a5-Vk for guile-devel@gnu.org; Mon, 14 Apr 2008 12:28:39 -0400 Original-Received: from main.gmane.org ([80.91.229.2] helo=ciao.gmane.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1JlRXq-0006QC-4s for guile-devel@gnu.org; Mon, 14 Apr 2008 12:28:38 -0400 Original-Received: from list by ciao.gmane.org with local (Exim 4.43) id 1JlRXl-00079m-7K for guile-devel@gnu.org; Mon, 14 Apr 2008 16:28:33 +0000 Original-Received: from 193.50.110.101 ([193.50.110.101]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Mon, 14 Apr 2008 16:28:33 +0000 Original-Received: from ludo by 193.50.110.101 with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Mon, 14 Apr 2008 16:28:33 +0000 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 312 Original-X-Complaints-To: usenet@ger.gmane.org X-Gmane-NNTP-Posting-Host: 193.50.110.101 X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: 26 Germinal an 216 de la =?iso-8859-1?Q?R=E9volution?= X-PGP-Key-ID: 0xEB1F5364 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 821D 815D 902A 7EAB 5CEE D120 7FBA 3D4F EB1F 5364 X-OS: i686-pc-linux-gnu User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux) Cancel-Lock: sha1:ED4CbiO1XuRZN4wyScpoXkP43cU= X-detected-kernel: by monty-python.gnu.org: Linux 2.6, seldom 2.4 (older, 4) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:7146 Archived-At: --=-=-= Hello, Small I/O functions like `scm_getc ()' deserve to be inlined. For instance, Andy measured it some time ago: http://thread.gmane.org/gmane.lisp.guile.devel/6639 I'm planning to apply the attached patch to both `master' and 1.8. To get an idea of its benefit, I run the attached "benchmark" (inspired from that in Guile-Reader) that does a lot of `read'. On my 1.2 GHz Intel Centrino, the inlining yields a 15% run-time improvement for that test. OK to apply? Thanks, Ludovic. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-Inline-scm_getc-scm_putc-and-scm_puts.patch Content-Description: The patch >From 4eeedb81429859b683277eee3af38532ee02733f Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Ludovic=20Court=C3=A8s?= Date: Mon, 14 Apr 2008 18:09:49 +0200 Subject: [PATCH] Inline `scm_getc', `scm_putc' and `scm_puts'. --- libguile/inline.h | 86 +++++++++++++++++++++++++++++++++++++++++++++++++--- libguile/ports.c | 60 +------------------------------------ libguile/ports.h | 5 +-- 3 files changed, 83 insertions(+), 68 deletions(-) diff --git a/libguile/inline.h b/libguile/inline.h index 8a6635e..8fa9a8c 100644 --- a/libguile/inline.h +++ b/libguile/inline.h @@ -25,17 +25,17 @@ "inline.c". */ -#include "libguile/__scm.h" - -#if (SCM_DEBUG_CELL_ACCESSES == 1) #include -#endif +#include + +#include "libguile/__scm.h" #include "libguile/pairs.h" #include "libguile/gc.h" #include "libguile/threads.h" #include "libguile/unif.h" -#include "libguile/pairs.h" +#include "libguile/ports.h" +#include "libguile/error.h" #ifndef SCM_INLINE_C_INCLUDING_INLINE_H @@ -85,6 +85,10 @@ SCM_API void scm_array_handle_set (scm_t_array_handle *h, ssize_t pos, SCM val); SCM_API int scm_is_pair (SCM x); +SCM_API int scm_getc (SCM port); +SCM_API void scm_putc (char c, SCM port); +SCM_API void scm_puts (const char *str_data, SCM port); + #endif @@ -285,5 +289,77 @@ scm_is_pair (SCM x) return SCM_I_CONSP (x); } + +/* Port I/O. */ + +#ifndef SCM_INLINE_C_INCLUDING_INLINE_H +SCM_C_EXTERN_INLINE +#endif +int +scm_getc (SCM port) +{ + int c; + scm_t_port *pt = SCM_PTAB_ENTRY (port); + + if (pt->rw_active == SCM_PORT_WRITE) + /* may be marginally faster than calling scm_flush. */ + scm_ptobs[SCM_PTOBNUM (port)].flush (port); + + if (pt->rw_random) + pt->rw_active = SCM_PORT_READ; + + if (pt->read_pos >= pt->read_end) + { + if (scm_fill_input (port) == EOF) + return EOF; + } + + c = *(pt->read_pos++); + + switch (c) + { + case '\a': + break; + case '\b': + SCM_DECCOL (port); + break; + case '\n': + SCM_INCLINE (port); + break; + case '\r': + SCM_ZEROCOL (port); + break; + case '\t': + SCM_TABCOL (port); + break; + default: + SCM_INCCOL (port); + break; + } + + return c; +} + +#ifndef SCM_INLINE_C_INCLUDING_INLINE_H +SCM_C_EXTERN_INLINE +#endif +void +scm_putc (char c, SCM port) +{ + SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port"); + scm_lfwrite (&c, 1, port); +} + +#ifndef SCM_INLINE_C_INCLUDING_INLINE_H +SCM_C_EXTERN_INLINE +#endif +void +scm_puts (const char *s, SCM port) +{ + SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port"); + scm_lfwrite (s, strlen (s), port); +} + + #endif #endif diff --git a/libguile/ports.c b/libguile/ports.c index c4ccca3..b25a7d0 100644 --- a/libguile/ports.c +++ b/libguile/ports.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -960,64 +960,6 @@ scm_fill_input (SCM port) return scm_ptobs[SCM_PTOBNUM (port)].fill_input (port); } -int -scm_getc (SCM port) -{ - int c; - scm_t_port *pt = SCM_PTAB_ENTRY (port); - - if (pt->rw_active == SCM_PORT_WRITE) - /* may be marginally faster than calling scm_flush. */ - scm_ptobs[SCM_PTOBNUM (port)].flush (port); - - if (pt->rw_random) - pt->rw_active = SCM_PORT_READ; - - if (pt->read_pos >= pt->read_end) - { - if (scm_fill_input (port) == EOF) - return EOF; - } - - c = *(pt->read_pos++); - - switch (c) - { - case '\a': - break; - case '\b': - SCM_DECCOL (port); - break; - case '\n': - SCM_INCLINE (port); - break; - case '\r': - SCM_ZEROCOL (port); - break; - case '\t': - SCM_TABCOL (port); - break; - default: - SCM_INCCOL (port); - break; - } - - return c; -} - -void -scm_putc (char c, SCM port) -{ - SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port"); - scm_lfwrite (&c, 1, port); -} - -void -scm_puts (const char *s, SCM port) -{ - SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port"); - scm_lfwrite (s, strlen (s), port); -} /* scm_lfwrite * diff --git a/libguile/ports.h b/libguile/ports.h index b93135e..fb0ef4e 100644 --- a/libguile/ports.h +++ b/libguile/ports.h @@ -3,7 +3,7 @@ #ifndef SCM_PORTS_H #define SCM_PORTS_H -/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2003, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -264,15 +264,12 @@ SCM_API SCM scm_eof_object_p (SCM x); SCM_API SCM scm_force_output (SCM port); SCM_API SCM scm_flush_all_ports (void); SCM_API SCM scm_read_char (SCM port); -SCM_API void scm_putc (char c, SCM port); -SCM_API void scm_puts (const char *str_data, SCM port); SCM_API size_t scm_c_read (SCM port, void *buffer, size_t size); SCM_API void scm_c_write (SCM port, const void *buffer, size_t size); SCM_API void scm_lfwrite (const char *ptr, size_t size, SCM port); SCM_API void scm_flush (SCM port); SCM_API void scm_end_input (SCM port); SCM_API int scm_fill_input (SCM port); -SCM_API int scm_getc (SCM port); SCM_API void scm_ungetc (int c, SCM port); SCM_API void scm_ungets (const char *s, int n, SCM port); SCM_API SCM scm_peek_char (SCM port); -- 1.5.5 --=-=-= Content-Type: application/octet-stream Content-Disposition: inline; filename*=us-ascii''%2c%2cio-bench.scm Content-Description: The benchmark (define %files-to-load (map %search-load-path '("ice-9/boot-9.scm" "ice-9/common-list.scm" "ice-9/format.scm" "ice-9/optargs.scm" "ice-9/session.scm" "ice-9/getopt-long.scm" "ice-9/psyntax.pp"))) ;; Number of iterations reading files. Adjust this as a function of your ;; machine's CPU power. (define %iterations 50) (define (load-file-with-reader file-name reader) (with-input-from-file file-name (lambda () (setvbuf (current-input-port) _IOFBF 4096) (let loop ((sexp (reader))) (if (eof-object? sexp) #t (loop (reader))))))) (define (how-long reader) ;; `get-internal-run-time' includes both system and user time. (define (time-elapsed) (tms:utime (times))) (let loop ((start (time-elapsed)) (iterations-left %iterations)) (if (= 0 iterations-left) (- (time-elapsed) start) (begin (for-each (lambda (file) (load-file-with-reader file reader)) %files-to-load) (loop start (- iterations-left 1)))))) (format #t "time elapsed: ~a~%" (how-long read)) ;; Timing: ;; master-with-inline-io: 161 ;; master: 191 ;; => 15% improvement --=-=-=--