Browse Source

Simplify ascii string concat and skip some allocations

With this simplified code it skips some allocations of byte slices

```
 benchstat old.bench new.bench
 name           old time/op    new time/op    delta
 ASCIIConcat-8    44.3µs ± 5%    40.2µs ±12%   -9.18%  (p=0.000 n=10+10)

 name           old alloc/op   new alloc/op   delta
 ASCIIConcat-8    14.0kB ± 0%     9.9kB ± 0%  -29.28%  (p=0.000 n=10+10)

 name           old allocs/op  new allocs/op  delta
 ASCIIConcat-8       131 ± 0%       121 ± 0%   -7.63%  (p=0.000 n=10+10)
```
Mihail Stoykov 3 years ago
parent
commit
4e41734c41
2 changed files with 17 additions and 4 deletions
  1. 1 4
      string_ascii.go
  2. 16 0
      string_test.go

+ 1 - 4
string_ascii.go

@@ -247,10 +247,7 @@ func (s asciiString) length() int {
 func (s asciiString) concat(other valueString) valueString {
 	switch other := other.(type) {
 	case asciiString:
-		b := make([]byte, len(s)+len(other))
-		copy(b, s)
-		copy(b[len(s):], other)
-		return asciiString(b)
+		return asciiString(s + other)
 	case unicodeString:
 		b := make([]uint16, len(s)+len(other))
 		b[0] = unistring.BOM

+ 16 - 0
string_test.go

@@ -12,3 +12,19 @@ func TestStringOOBProperties(t *testing.T) {
 
 	testScript1(SCRIPT, valueInt(1), t)
 }
+
+func BenchmarkASCIIConcat(b *testing.B) {
+	vm := New()
+
+	b.ResetTimer()
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		_, err := vm.RunString(`{let result = "ab";
+		for (let i = 0 ; i < 10;i++) {
+			result += result;
+		}}`)
+		if err != nil {
+			b.Fatalf("Unexpected errors %s", err)
+		}
+	}
+}