[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