mirror of
https://github.com/golang/go
synced 2024-11-21 19:04:44 -07:00
gc: make string x + y + z + ... + w efficient
1 malloc per concatenation. R=ken2 CC=golang-dev https://golang.org/cl/2124045
This commit is contained in:
parent
698fb4f192
commit
f47d403cb4
@ -20,7 +20,7 @@ char *runtimeimport =
|
||||
"func \"\".printnl ()\n"
|
||||
"func \"\".printsp ()\n"
|
||||
"func \"\".printf ()\n"
|
||||
"func \"\".catstring (? string, ? string) string\n"
|
||||
"func \"\".concatstring ()\n"
|
||||
"func \"\".cmpstring (? string, ? string) int\n"
|
||||
"func \"\".slicestring (? string, ? int, ? int) string\n"
|
||||
"func \"\".slicestring1 (? string, ? int) string\n"
|
||||
|
@ -33,7 +33,9 @@ func printnl()
|
||||
func printsp()
|
||||
func printf()
|
||||
|
||||
func catstring(string, string) string
|
||||
// filled in by compiler: int n, string, string, ...
|
||||
func concatstring()
|
||||
|
||||
func cmpstring(string, string) int
|
||||
func slicestring(string, int, int) string
|
||||
func slicestring1(string, int) string
|
||||
|
@ -17,6 +17,7 @@ static void heapmoves(void);
|
||||
static NodeList* paramstoheap(Type **argin, int out);
|
||||
static NodeList* reorder1(NodeList*);
|
||||
static NodeList* reorder3(NodeList*);
|
||||
static Node* addstr(Node*, NodeList**);
|
||||
|
||||
static NodeList* walkdefstack;
|
||||
|
||||
@ -1205,10 +1206,7 @@ walkexpr(Node **np, NodeList **init)
|
||||
goto ret;
|
||||
|
||||
case OADDSTR:
|
||||
// sys_catstring(s1, s2)
|
||||
n = mkcall("catstring", n->type, init,
|
||||
conv(n->left, types[TSTRING]),
|
||||
conv(n->right, types[TSTRING]));
|
||||
n = addstr(n, init);
|
||||
goto ret;
|
||||
|
||||
case OSLICESTR:
|
||||
@ -2234,3 +2232,42 @@ mapfn(char *name, Type *t)
|
||||
argtype(fn, t->type);
|
||||
return fn;
|
||||
}
|
||||
|
||||
static Node*
|
||||
addstr(Node *n, NodeList **init)
|
||||
{
|
||||
Node *r, *cat, *typstr;
|
||||
NodeList *in, *args;
|
||||
int i, count;
|
||||
|
||||
count = 0;
|
||||
for(r=n; r->op == OADDSTR; r=r->left)
|
||||
count++; // r->right
|
||||
count++; // r
|
||||
|
||||
// prepare call of runtime.catstring of type int, string, string, string
|
||||
// with as many strings as we have.
|
||||
cat = syslook("concatstring", 1);
|
||||
cat->type = T;
|
||||
cat->ntype = nod(OTFUNC, N, N);
|
||||
in = list1(nod(ODCLFIELD, N, typenod(types[TINT]))); // count
|
||||
typstr = typenod(types[TSTRING]);
|
||||
for(i=0; i<count; i++)
|
||||
in = list(in, nod(ODCLFIELD, N, typstr));
|
||||
cat->ntype->list = in;
|
||||
cat->ntype->rlist = list1(nod(ODCLFIELD, N, typstr));
|
||||
|
||||
args = nil;
|
||||
for(r=n; r->op == OADDSTR; r=r->left)
|
||||
args = concat(list1(conv(r->right, types[TSTRING])), args);
|
||||
args = concat(list1(conv(r, types[TSTRING])), args);
|
||||
args = concat(list1(nodintconst(count)), args);
|
||||
|
||||
r = nod(OCALL, cat, N);
|
||||
r->list = args;
|
||||
typecheck(&r, Erv);
|
||||
walkexpr(&r, init);
|
||||
r->type = n->type;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -395,6 +395,7 @@ void memmove(void*, void*, uint32);
|
||||
void* mal(uintptr);
|
||||
uint32 cmpstring(String, String);
|
||||
String catstring(String, String);
|
||||
String concatstring(int32, String*);
|
||||
String gostring(byte*);
|
||||
String gostringn(byte*, int32);
|
||||
String gostringnocopy(byte*);
|
||||
|
@ -114,9 +114,33 @@ catstring(String s1, String s2)
|
||||
return s3;
|
||||
}
|
||||
|
||||
String
|
||||
concatstring(int32 n, String *s)
|
||||
{
|
||||
int32 i, l;
|
||||
String out;
|
||||
|
||||
func catstring(s1 String, s2 String) (s3 String) {
|
||||
s3 = catstring(s1, s2);
|
||||
l = 0;
|
||||
for(i=0; i<n; i++) {
|
||||
if(l + s[i].len < l)
|
||||
throw("string concatenation too long");
|
||||
l += s[i].len;
|
||||
}
|
||||
|
||||
out = gostringsize(l);
|
||||
l = 0;
|
||||
for(i=0; i<n; i++) {
|
||||
mcpy(out.str+l, s[i].str, s[i].len);
|
||||
l += s[i].len;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
#pragma textflag 7
|
||||
// s1 is the first of n strings.
|
||||
// the output string follows.
|
||||
func concatstring(n int32, s1 String) {
|
||||
(&s1)[n] = concatstring(n, &s1);
|
||||
}
|
||||
|
||||
uint32
|
||||
|
Loading…
Reference in New Issue
Block a user