[uim-commit] r1635 - branches/r5rs/sigscheme

kzk at freedesktop.org kzk at freedesktop.org
Wed Sep 28 01:08:19 PDT 2005


Author: kzk
Date: 2005-09-28 01:08:16 -0700 (Wed, 28 Sep 2005)
New Revision: 1635

Modified:
   branches/r5rs/sigscheme/TODO
   branches/r5rs/sigscheme/operations.c
Log:
* optimize "map", not to use "reverse" and "vector"

* sigscheme/operations.c
  - (ScmOp_map): split content into map_singular_arg and
    map_plural_args
  - (map_singular_arg, map_plural_args): new func
* sigscheme/TODO
  - update


Modified: branches/r5rs/sigscheme/TODO
===================================================================
--- branches/r5rs/sigscheme/TODO	2005-09-28 07:14:02 UTC (rev 1634)
+++ branches/r5rs/sigscheme/TODO	2005-09-28 08:08:16 UTC (rev 1635)
@@ -36,8 +36,6 @@
 ==============================================================================
 Performance improvements:
 
-* Optimize ScmOp_map()
-
 * Object representation compaction ([Anthy-dev 2353], [Anthy-dev 2360])
 
 * Replace almost ScmObj initialization by SCM_NULL with SCM_FALSE. SCM_NULL is

Modified: branches/r5rs/sigscheme/operations.c
===================================================================
--- branches/r5rs/sigscheme/operations.c	2005-09-28 07:14:02 UTC (rev 1634)
+++ branches/r5rs/sigscheme/operations.c	2005-09-28 08:08:16 UTC (rev 1635)
@@ -63,6 +63,9 @@
 static int ScmOp_c_length(ScmObj lst);
 static ScmObj ScmOp_listtail_internal(ScmObj obj, int k);
 
+static ScmObj map_singular_arg(ScmObj proc, ScmObj args);
+static ScmObj map_plural_args(ScmObj proc, ScmObj args);
+
 /*=======================================
   Function Implementations
 =======================================*/
@@ -1716,61 +1719,92 @@
     return (FUNCP(obj) || CLOSUREP(obj)) ? SCM_TRUE : SCM_FALSE;
 }
 
-/* FIXME: excessive memory consumptions (reverse, vector) */
-ScmObj ScmOp_map(ScmObj map_arg, ScmObj env)
+ScmObj ScmOp_map(ScmObj args, ScmObj env)
 {
-    int arg_len = SCM_INT_VALUE(ScmOp_length(map_arg));
-    ScmObj proc = CAR(map_arg);
-    ScmObj args = SCM_NULL;
-    ScmObj ret  = SCM_NULL;
-    ScmObj tmp  = SCM_NULL;
+    ScmObj proc = CAR(args);
+    int arg_len = SCM_INT_VALUE(ScmOp_length(args));
 
-    ScmObj arg_vector = SCM_NULL;
-    ScmObj arg1       = SCM_NULL;
-    int vector_len = 0;
-    int i = 0;
-
     /* arglen check */
     if (arg_len < 2)
         SigScm_Error("map : Wrong number of arguments");
 
     /* 1proc and 1arg case */
-    if (arg_len == 2) {
-        /* apply func to each item */
-        for (args = CADR(map_arg); !NULLP(args); args = CDR(args)) {
-            /* apply proc */
-            ret = CONS(Scm_call(proc, LIST_1(CAR(args))), ret);
+    if (arg_len == 2)
+        return map_singular_arg(proc, CADR(args));
+
+    /* 1proc and many args case */
+    return map_plural_args(proc, CDR(args));
+}
+
+static ScmObj map_singular_arg(ScmObj proc, ScmObj args)
+{
+    ScmObj ret      = SCM_NULL;
+    ScmObj ret_tail = SCM_FALSE;
+
+    if (NULLP(args))
+        return SCM_NULL;
+
+    for (; !NULLP(args); args = CDR(args)) {
+        if (NFALSEP(ret)) {
+            /* lasting */
+            SET_CDR(ret_tail, CONS(Scm_call(proc, LIST_1(CAR(args))), SCM_NULL));
+            ret_tail = CDR(ret_tail);
+
+        } else {
+            /* first */
+            ret = CONS(Scm_call(proc, LIST_1(CAR(args))), SCM_NULL);
+            ret_tail = ret;
         }
-        return ScmOp_reverse(ret);
     }
 
-    /* 1proc and many args case */
-    arg_vector = ScmOp_list2vector(CDR(map_arg));
-    vector_len = SCM_VECTOR_LEN(arg_vector);
+    return ret;
+}
+
+static ScmObj map_plural_args(ScmObj proc, ScmObj args)
+{
+    ScmObj map_arg      = SCM_FALSE;
+    ScmObj map_arg_tail = SCM_FALSE;
+    ScmObj tmp_lsts     = SCM_FALSE;
+    ScmObj lst          = SCM_FALSE;
+    ScmObj ret          = SCM_FALSE;
+    ScmObj ret_tail     = SCM_FALSE;
+
     while (1) {
-        /* create arg */
-        arg1 = SCM_NULL;
-        for (i = 0; i < vector_len; i++) {
-            tmp  = SCM_VECTOR_CREF(arg_vector, i);
-            /* check if we can continue next loop */
-            if (NULLP(tmp)) {
-                /* if next item is SCM_NULL, let's return! */
-                return ScmOp_reverse(ret);
+        /* construct map_arg */
+        map_arg  = SCM_NULL;
+        tmp_lsts = args;
+        for (; !NULLP(tmp_lsts); tmp_lsts = CDR(tmp_lsts)) {
+            lst = CAR(tmp_lsts);
+            if (NULLP(lst))
+                return ret;
+
+            if (NFALSEP(map_arg)) {
+                /* lasting */
+                SET_CDR(map_arg_tail, CONS(CAR(lst), SCM_NULL));
+                map_arg_tail = CDR(map_arg_tail);
+            } else {
+                /* first */
+                map_arg = CONS(CAR(lst), SCM_NULL);
+                map_arg_tail = map_arg;
             }
 
-            arg1 = CONS(CAR(tmp), arg1);
-            SCM_VECTOR_SET_CREF(arg_vector, i, CDR(tmp));
+            /* update tmp_lsts */
+            SET_CAR(tmp_lsts, CDR(lst));
         }
 
-        /* reverse arg */
-        arg1 = ScmOp_reverse(arg1);
-
-        /* apply proc to arg1 */
-        ret = CONS(Scm_call(proc, arg1), ret);
+        /* construct ret */
+        if (NFALSEP(ret)) {
+            /* lasting */
+            SET_CDR(ret_tail, CONS(Scm_call(proc, map_arg), SCM_NULL));
+            ret_tail = CDR(ret_tail);
+        } else {
+            /* first */
+            ret = CONS(Scm_call(proc, map_arg), SCM_NULL);
+            ret_tail = ret;
+        }
     }
 
-    /* never reaches here */
-    SigScm_Error("map bug?");
+    SigScm_Error("map : invalid argument ", args);
     return SCM_NULL;
 }
 



More information about the uim-commit mailing list