Commit 69cd91a5 authored by Dmitry Vyukov's avatar Dmitry Vyukov

cmd/gc: don't copy []byte during string comparison

Currently we allocate a new string during []byte->string conversion
in string comparison expressions. String allocation is unnecessary in
this case, because comparison does memorize the strings for later use.
This change uses slicebytetostringtmp to construct temp string directly
from []byte buffer and passes it to runtime.eqstring.

Change-Id: If00f1faaee2076baa6f6724d245d5b5e0f59b563
Reviewed-on: https://go-review.googlesource.com/3410Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 4737399b
......@@ -1031,6 +1031,18 @@ orderexpr(Node **np, Order *order)
}
break;
case OCMPSTR:
orderexpr(&n->left, order);
orderexpr(&n->right, order);
// Mark string(byteSlice) arguments to reuse byteSlice backing
// buffer during conversion. String comparison does not
// memorize the strings for later use, so it is safe.
if(n->left->op == OARRAYBYTESTR)
n->left->op = OARRAYBYTESTRTMP;
if(n->right->op == OARRAYBYTESTR)
n->right->op = OARRAYBYTESTRTMP;
break;
case OINDEXMAP:
// key must be addressable
orderexpr(&n->left, order);
......
......@@ -76,6 +76,7 @@ func slicebytetostringtmp(b []byte) string {
// First such case is a m[string(k)] lookup where
// m is a string-keyed map and k is a []byte.
// Second such case is "<"+string(b)+">" concatenation where b is []byte.
// Third such case is string(b)=="foo" comparison where b is []byte.
if raceenabled && len(b) > 0 {
racereadrangepc(unsafe.Pointer(&b[0]),
......
......@@ -158,3 +158,20 @@ func TestGostringnocopy(t *testing.T) {
t.Errorf("want %d, got %d", max+9, newmax)
}
}
func TestCompareTempString(t *testing.T) {
s := "foo"
b := []byte(s)
n := testing.AllocsPerRun(1000, func() {
if string(b) != s {
t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
}
if string(b) == s {
} else {
t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
}
})
if n != 0 {
t.Fatalf("want 0 allocs, got %v", n)
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment