Skip to content

Instantly share code, notes, and snippets.

@MasterDuke17
Created September 23, 2017 23:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MasterDuke17/9cdf715bc10093721345db9e1e15ecf5 to your computer and use it in GitHub Desktop.
Save MasterDuke17/9cdf715bc10093721345db9e1e15ecf5 to your computer and use it in GitHub Desktop.
diff --git a/src/strings/ops.c b/src/strings/ops.c
index 080951f7..9c2e9d08 100644
--- a/src/strings/ops.c
+++ b/src/strings/ops.c
@@ -1616,6 +1616,7 @@ MVMString * MVM_string_join(MVMThreadContext *tc, MVMString *separator, MVMObjec
MVMuint16 sstrands, total_strands;
MVMint32 concats_stable = 1;
size_t bytes;
+ int all_strands_of_same_type, strand_type;
MVM_string_check_arg(tc, separator, "join separator");
if (!IS_CONCRETE(input))
@@ -1637,6 +1638,10 @@ MVMString * MVM_string_join(MVMThreadContext *tc, MVMString *separator, MVMObjec
});
});
+ all_strands_of_same_type = separator->body.storage_type == MVM_STRING_STRAND;
+ if (all_strands_of_same_type)
+ strand_type = separator->body.storage.strands->blob_string->body.storage_type;
+
/* Take a first pass through the string, counting up length and the total
* number of strands we encounter as well as building a flat array of the
* strings (to we only have to do the indirect calls once). */
@@ -1667,6 +1672,10 @@ MVMString * MVM_string_join(MVMThreadContext *tc, MVMString *separator, MVMObjec
piece = MVM_repr_get_str(tc, item);
}
+ if (all_strands_of_same_type)
+ all_strands_of_same_type = piece->body.storage_type == MVM_STRING_STRAND &&
+ strand_type == piece->body.storage.strands->blob_string->body.storage_type;
+
/* If it wasn't the first piece, add separator here. */
if (num_pieces) {
total_strands += sstrands;
@@ -1695,11 +1704,22 @@ MVMString * MVM_string_join(MVMThreadContext *tc, MVMString *separator, MVMObjec
/* If we just collect all the things as strands, are we within bounds, and
* will be come out ahead? */
- if (total_strands < MVM_STRING_MAX_STRANDS && 16 <= total_graphs / total_strands) {
- /* XXX TODO: Implement this, conditionalize branch thing below. */
+ if (total_strands < MVM_STRING_MAX_STRANDS && all_strands_of_same_type) {
+ size_t offset = 0;
+ result->body.storage_type = MVM_STRING_STRAND;
+ result->body.storage.strands = allocate_strands(tc, total_strands);
+ result->body.num_strands = total_strands;
+ for (i = 0; i < num_pieces; i++) {
+ MVMString *piece = pieces[i];
+ if (0 < i) {
+ copy_strands(tc, separator, 0, result, offset, separator->body.num_strands);
+ offset += separator->body.num_strands;
+ }
+ copy_strands(tc, piece, 0, result, offset, piece->body.num_strands);
+ offset += piece->body.num_strands;
+ }
}
- /*else {*/
- if (1) {
+ else {
/* We'll produce a single, flat string. */
MVMint64 position = 0;
MVMGraphemeIter gi;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment