From xemacs-m  Sat May  3 09:59:50 1997
Received: from jagor.srce.hr (hniksic@jagor.srce.hr [161.53.2.130])
	by xemacs.org (8.8.5/8.8.5) with ESMTP id JAA01615
	for <xemacs-beta@xemacs.org>; Sat, 3 May 1997 09:59:48 -0500 (CDT)
Received: (from hniksic@localhost)
          by jagor.srce.hr (8.8.5/8.8.4)
	  id QAA11025; Sat, 3 May 1997 16:59:48 +0200 (MET DST)
To: XEmacs Developers <xemacs-beta@xemacs.org>
Subject: `mapcar' calling SUBRs directly
X-Save-Project-Gutenberg: <URL:http://www.promo.net/pg/nl/pgny_nov96.html>
X-Attribution: Hrv
X-Face: Mie8:rOV<\c/~z{s.X4A{!?vY7{drJ([U]0O=W/<W*SMo/Mv:58:*_y~ki>xDi&N7XG
        KV^$k0m3Oe/)'e%3=$PCR&3ITUXH,cK>]bci&<qQ>Ff%x_>1`T(+M2Gg/fgndU%k*ft
        [(7._6e0n-V%|%'[c|q:;}td$#INd+;?!-V=c8Pqf}3J
From: Hrvoje Niksic <hniksic@srce.hr>
Date: 03 May 1997 16:59:47 +0200
Message-ID: <kigenbomwik.fsf@jagor.srce.hr>
Lines: 129
X-Mailer: Gnus v5.4.50/XEmacs 19.15

Here is the patch that avoids using `call1' when `mapcar' is called
with a SUBR (or a symbol whose function is a SUBR) taking exactly one
argument.  Since it patches `mapcar1', it affects all of the
mapcar-related functions, e.g. `mapcar' `mapc-internal' (and `mapc'),
`mapconcat', It seems to be stable stuff, unless there is a fuckup
unforeseen by me (like a missing GCPRO) involved somewhere.

I am still unsure of GCPRO, even after reading that section of
internals.info.  Am I totally dumb?  Can someone explain to me in
gentle words which variables I should protect?  For example, should
`Lisp_Object func' in this patch be GCPRO-ed?

I'd like someone to actually time this stuff, to see:

1) the performance-gain (if any) of `mapcar' called with a SUBR

2) the overall performance-gain on a typical XEmacs session

Patch follows:

--- src/fns.c.orig	Sat May  3 02:26:40 1997
+++ src/fns.c	Sat May  3 16:51:49 1997
@@ -3165,12 +3165,37 @@
 {
   Lisp_Object tail;
   Lisp_Object dummy = Qnil;
+  lisp_fn_t subr;
   int i;
   struct gcpro gcpro1, gcpro2, gcpro3;
   Lisp_Object result;
 
   GCPRO3 (dummy, fn, seq);
 
+  subr = NULL;
+
+  /* Recognize whether FN is a subr, or a symbol whose symbol-function
+     is a subr.  If yes, and the subr takes exactly one argument, make
+     subr point to the C code of the subr itself.  */
+  if (SUBRP (fn))
+    {
+      if (XSUBR (fn)->min_args == 1 && XSUBR (fn)->max_args == 1)
+	{
+	  subr = subr_function (XSUBR (fn));
+	}
+    }
+  else if (SYMBOLP (fn))
+    {
+      Lisp_Object func = XSYMBOL (fn)->function;
+
+      if (SUBRP (func)
+	  && XSUBR (func)->min_args == 1
+	  && XSUBR (func)->max_args == 1)
+	{
+	  subr = subr_function (XSUBR (func));
+	}
+    }
+
   if (vals)
     {
       /* Don't let vals contain any garbage when GC happens.  */
@@ -3189,7 +3214,10 @@
       for (i = 0; i < leni; i++)
 	{
 	  dummy = vector_data (XVECTOR (seq))[i];
-	  result = call1 (fn, dummy);
+	  if (subr)
+	    result = subr (dummy);
+	  else
+	    result = call1 (fn, dummy);
 	  if (vals)
 	    vals[i] = result;
 	}
@@ -3200,7 +3228,10 @@
       for (i = 0; i < leni; i++)
 	{
 	  XSETINT (dummy, bit_vector_bit (v, i));
-	  result = call1 (fn, dummy);
+	  if (subr)
+	    result = subr (dummy);
+	  else
+	    result = call1 (fn, dummy);
 	  if (vals)
 	    vals[i] = result;
 	}
@@ -3209,7 +3240,10 @@
     {
       for (i = 0; i < leni; i++)
 	{
-	  result = call1 (fn, make_char (string_char (XSTRING (seq), i)));
+	  if (subr)
+	    result = subr (make_char (string_char (XSTRING (seq), i)));
+	  else
+	    result = call1 (fn, make_char (string_char (XSTRING (seq), i)));
 	  if (vals)
 	    vals[i] = result;
 	}
@@ -3219,7 +3253,10 @@
       tail = seq;
       for (i = 0; i < leni; i++)
 	{
-	  result = call1 (fn, Fcar (tail));
+	  if (subr)
+	    result = subr (Fcar (tail));
+	  else
+	    result = call1 (fn, Fcar (tail));
 	  if (vals)
 	    vals[i] = result;
 	  tail = Fcdr (tail);
--- src/ChangeLog.orig	Sat May  3 02:26:38 1997
+++ src/ChangeLog	Sat May  3 16:57:26 1997
@@ -19,6 +19,11 @@
 
 	* buffer.c (Fmake_indirect_buffer): Don't pretend it's there.
 
+Sat May  3 15:33:59 1997  Hrvoje Niksic  <hniksic@srce.hr>
+
+	* fns.c (mapcar1): If FN is subr, invoke it directly instead
+	of using `call1'.
+
 Fri Apr 25 10:53:07 1997  Steven L Baur  <steve@altair.xemacs.org>
 
 	* glyphs-x.c: libpng already includes setjmp.h, so don't attempt


-- 
Hrvoje Niksic <hniksic@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
You'll notice that perl is not itself written in Perl.
                                                 -- The Perl FAQ

