summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2016-04-28 07:54:07 +0200
committerAndy Wingo <wingo@pobox.com>2016-04-28 08:16:43 +0200
commit8b46a4af446d2015976b1d9c09888a75260ebc2b (patch)
tree6a966fc1c2bc0a581bde139b110445830853d499
parentee4854a315a902d64c6de0ff27ac2d423dc75600 (diff)
downloadguile-8b46a4af446d2015976b1d9c09888a75260ebc2b.tar.gz
Optimize peek-char
* libguile/ports.c (scm_peek_char): Optimize. A loop calling peek-char on a buffered string port 10e6 times goes down from 50ns/iteration to 32ns/iteration.
-rw-r--r--libguile/ports.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/libguile/ports.c b/libguile/ports.c
index cc33bd905..394d632e7 100644
--- a/libguile/ports.c
+++ b/libguile/ports.c
@@ -2124,17 +2124,29 @@ SCM_DEFINE (scm_peek_char, "peek-char", 0, 1, 0,
"sequence when the error is raised.\n")
#define FUNC_NAME s_scm_peek_char
{
- int err;
+ int first_byte, err;
SCM result;
scm_t_wchar c;
char bytes[SCM_MBCHAR_BUF_SIZE];
long column, line;
size_t len = 0;
+ scm_t_port_internal *pti;
if (SCM_UNBNDP (port))
port = scm_current_input_port ();
SCM_VALIDATE_OPINPORT (1, port);
+ pti = SCM_PORT_GET_INTERNAL (port);
+
+ /* First, a couple fast paths. */
+ first_byte = peek_byte_or_eof (port);
+ if (first_byte == EOF)
+ return SCM_EOF_VAL;
+ if (pti->encoding_mode == SCM_PORT_ENCODING_MODE_LATIN1)
+ return SCM_MAKE_CHAR (first_byte);
+ if (pti->encoding_mode == SCM_PORT_ENCODING_MODE_UTF8 && first_byte < 0x80)
+ return SCM_MAKE_CHAR (first_byte);
+ /* Now the slow paths. */
column = SCM_COL (port);
line = SCM_LINUM (port);