Thanks for reminding me the issue.
I'm still not sure a nice way to incorporate that
"optimization" in port.c, v1.69. Somethings smells nasty;
it looks unnecessarily compilicated.
However, I noticed another big overhead in the current
implementation, related to the locking of the port.
Please try the following patch. At least in my tests,
I see over 8x speedup.
For "while" and "until" macros, I'm still not sure if
it's worth to make them builtin macros or not. Especially
for "while", it is very common that you want to use the result
of the test in the body. Something like "anaphoric while"
(as described in Paul Graham's "On Lisp"), but uses explicit
variables, would be more useful. Any ideas?
--shiro
===================================================================
RCS file: /cvsroot/gauche/Gauche/src/portapi.c,v
retrieving revision 1.12
diff -u -r1.12 portapi.c
--- portapi.c 5 Jul 2003 03:29:12 -0000 1.12
+++ portapi.c 10 Aug 2003 06:20:10 -0000
@@ -683,42 +683,54 @@
* Reads up to EOL or EOF.
*/
-/* Readline can be optimized by directly scanning the buffer instead of
- reading one char at a time, bypassing mb->char->mb conversion and
- DString creation. There was a some attempt to implement it; see
- port.c, v1.69 for details. For now, I drop that. */
+/* Auxiliary procedures */
-#ifdef SAFE_PORT_OP
-ScmObj Scm_ReadLine(ScmPort *p)
-#else
-ScmObj Scm_ReadLineUnsafe(ScmPort *p)
-#endif
+#ifndef READLINE_AUX
+#define READLINE_AUX
+/* Assumes the port is locked, and the caller takes care of unlocking
+ even if an error is signalled within this body */
+ScmObj readline_body(ScmPort *p)
{
int c1 = 0, c2 = 0;
ScmDString ds;
- VMDECL;
- SHORTCUT(p, return Scm_ReadLineUnsafe(p));
Scm_DStringInit(&ds);
- LOCK(p);
- SAFE_CALL(p, c1 = Scm_GetcUnsafe(p));
- if (c1 == EOF) {
- UNLOCK(p);
- return SCM_EOF;
- }
+ c1 = Scm_GetcUnsafe(p);
+ if (c1 == EOF) return SCM_EOF;
for (;;) {
if (c1 == EOF || c1 == '\n') break;
if (c1 == '\r') {
- SAFE_CALL(p, c2 = Scm_GetcUnsafe(p));
+ c2 = Scm_GetcUnsafe(p);
if (c2 == EOF || c2 == '\n') break;
Scm_UngetcUnsafe(c2, p);
break;
}
SCM_DSTRING_PUTC(&ds, c1);
- SAFE_CALL(p, c1 = Scm_GetcUnsafe(p));
+ c1 = Scm_GetcUnsafe(p);
}
- UNLOCK(p);
return Scm_DStringGet(&ds);
+}
+#endif /* READLINE_AUX */
+
+/*
+ * The optmized version of readline. If the input is a buffered
+ * port or an input string, it tries to avoid mb->wc->mb conversion.
+ */
+
+#ifdef SAFE_PORT_OP
+ScmObj Scm_ReadLine(ScmPort *p)
+#else
+ScmObj Scm_ReadLineUnsafe(ScmPort *p)
+#endif
+{
+ ScmObj r;
+ VMDECL;
+ SHORTCUT(p, return Scm_ReadLineUnsafe(p));
+
+ LOCK(p);
+ SAFE_CALL(p, r = readline_body(p));
+ UNLOCK(p);
+ return r;
}
/*=================================================================
|