[svn:parrot] r48781 - trunk/src/string

chromatic at svn.parrot.org chromatic at svn.parrot.org
Sat Sep 4 15:03:51 UTC 2010


Author: chromatic
Date: Sat Sep  4 15:03:50 2010
New Revision: 48781
URL: https://trac.parrot.org/parrot/changeset/48781

Log:
[str] Rearranged Parrot_str_join() for efficiency.

Modified:
   trunk/src/string/api.c

Modified: trunk/src/string/api.c
==============================================================================
--- trunk/src/string/api.c	Sat Sep  4 15:03:48 2010	(r48780)
+++ trunk/src/string/api.c	Sat Sep  4 15:03:50 2010	(r48781)
@@ -3246,115 +3246,117 @@
 Parrot_str_join(PARROT_INTERP, ARGIN_NULLOK(STRING *j), ARGIN(PMC *ar))
 {
     ASSERT_ARGS(Parrot_str_join)
-    STRING  **chunks;
-    STRING   *res;
-    STRING   *s;
     PMC      *sb;
-    char     *pos;
-    const int ar_len       = VTABLE_elements(interp, ar);
-    int       total_length = 0;
-    int       transcoded   = 0;
-    int       i;
-
-    if (ar_len == 0)
-        return Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
 
     if (STRING_IS_NULL(j)) {
         sb = Parrot_pmc_new_init(interp, enum_class_StringBuilder, ar);
         return VTABLE_get_string(interp, sb);
     }
+    else {
+        const int ar_len = VTABLE_elements(interp, ar);
+        STRING  **chunks;
+        STRING   *res;
+        STRING   *s;
+        char     *pos;
+        int       total_length = 0;
+        int       transcoded   = 0;
+        int       i;
 
-    /* We don't mark "chunks". So block GC here to avoid crash */
-    Parrot_block_GC_mark(interp);
+        if (ar_len == 0)
+            return Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
 
-    chunks = (STRING **)Parrot_gc_allocate_fixed_size_storage(interp,
-        ar_len * sizeof (STRING *));
+        /* We don't mark "chunks". So block GC here to avoid crash */
+        Parrot_block_GC_mark(interp);
 
-    for (i = 0; i < ar_len; ++i) {
-        STRING *next = VTABLE_get_string_keyed_int(interp, ar, i);
+        chunks = (STRING **)Parrot_gc_allocate_fixed_size_storage(interp,
+            ar_len * sizeof (STRING *));
 
-        if (STRING_IS_NULL(next)) {
-            chunks[i] = STRINGNULL;
-            continue;
-        }
+        for (i = 0; i < ar_len; ++i) {
+            STRING *next = VTABLE_get_string_keyed_int(interp, ar, i);
 
-        if (next->encoding != j->encoding) {
-            const ENCODING *e = j->encoding;
+            if (STRING_IS_NULL(next)) {
+                chunks[i] = STRINGNULL;
+                continue;
+            }
 
-            string_rep_compatible(interp, next, j, &e);
-            if (e == Parrot_fixed_8_encoding_ptr)
-                e = Parrot_utf8_encoding_ptr;
-            j           = e->to_encoding(interp, j);
-            transcoded  = 1;
-        }
+            if (next->encoding != j->encoding) {
+                const ENCODING *e = j->encoding;
 
-        chunks[i]     = next;
-        total_length += next->bufused;
-    }
+                string_rep_compatible(interp, next, j, &e);
+                if (e == Parrot_fixed_8_encoding_ptr)
+                    e = Parrot_utf8_encoding_ptr;
+                j           = e->to_encoding(interp, j);
+                transcoded  = 1;
+            }
 
-    /* with the right charset, transcode any strings if necessary */
-    if (transcoded) {
-        const CHARSET  *c = j->charset;
-        const ENCODING *e = j->encoding;
+            chunks[i]     = next;
+            total_length += next->bufused;
+        }
 
-        for (i = 0; i < ar_len; ++i) {
-            STRING *s = chunks[i];
+        /* with the right charset, transcode any strings if necessary */
+        if (transcoded) {
+            const CHARSET  *c = j->charset;
+            const ENCODING *e = j->encoding;
 
-            if (STRING_IS_NULL(s))
-                continue;
+            for (i = 0; i < ar_len; ++i) {
+                STRING *s = chunks[i];
+
+                if (STRING_IS_NULL(s))
+                    continue;
 
-            if (s->encoding != e || s->charset != c) {
-                STRING *new_s = e->to_encoding(interp, s);
-                chunks[i]     = new_s;
-                total_length += new_s->bufused - s->bufused;
+                if (s->encoding != e || s->charset != c) {
+                    STRING *new_s = e->to_encoding(interp, s);
+                    chunks[i]     = new_s;
+                    total_length += new_s->bufused - s->bufused;
+                }
             }
         }
-    }
 
-    /* add the length of the separator, now that it's transcoded */
-    total_length += j->bufused * ar_len;
+        /* add the length of the separator, now that it's transcoded */
+        total_length += j->bufused * ar_len;
 
-    res = Parrot_gc_new_string_header(interp, 0);
-    Parrot_gc_allocate_string_storage(interp, res, total_length);
+        res = Parrot_gc_new_string_header(interp, 0);
+        Parrot_gc_allocate_string_storage(interp, res, total_length);
 
-    res->charset  = j->charset;
-    res->encoding = j->encoding;
+        res->charset  = j->charset;
+        res->encoding = j->encoding;
 
-    /* Iterate over chunks and append it to res */
-    pos = res->strstart;
-
-    /* Copy first chunk */
-    s = chunks[0];
-    if (!STRING_IS_NULL(s)) {
-        mem_sys_memcopy(pos, s->strstart, s->bufused);
-        pos += s->bufused;
-    }
+        /* Iterate over chunks and append it to res */
+        pos = res->strstart;
+
+        /* Copy first chunk */
+        s = chunks[0];
+        if (!STRING_IS_NULL(s)) {
+            mem_sys_memcopy(pos, s->strstart, s->bufused);
+            pos += s->bufused;
+        }
 
-    for (i = 1; i < ar_len; ++i) {
-        STRING *next = chunks[i];
+        for (i = 1; i < ar_len; ++i) {
+            STRING *next = chunks[i];
 
-        if (STRING_IS_NULL(next))
-            continue;
+            if (STRING_IS_NULL(next))
+                continue;
 
-        mem_sys_memcopy(pos, j->strstart, j->bufused);
-        pos += j->bufused;
+            mem_sys_memcopy(pos, j->strstart, j->bufused);
+            pos += j->bufused;
 
-        mem_sys_memcopy(pos, next->strstart, next->bufused);
-        pos += next->bufused;
+            mem_sys_memcopy(pos, next->strstart, next->bufused);
+            pos += next->bufused;
 
-        /* We can consume all buffer and pos will be next-after-end of buffer */
-        PARROT_ASSERT(pos <= res->strstart + Buffer_buflen(res) + 1);
-    }
+            /* We can consume all buffer and pos will be next-after-end of buffer */
+            PARROT_ASSERT(pos <= res->strstart + Buffer_buflen(res) + 1);
+        }
 
-    res->bufused  = pos - res->strstart;
-    res->strlen = CHARSET_CODEPOINTS(interp, res);
+        res->bufused  = pos - res->strstart;
+        res->strlen = CHARSET_CODEPOINTS(interp, res);
 
-    Parrot_gc_free_fixed_size_storage(interp, ar_len * sizeof (STRING *),
-        chunks);
+        Parrot_gc_free_fixed_size_storage(interp, ar_len * sizeof (STRING *),
+            chunks);
 
-    Parrot_unblock_GC_mark(interp);
+        Parrot_unblock_GC_mark(interp);
 
-    return res;
+        return res;
+    }
 }
 
 


More information about the parrot-commits mailing list