Browse Source

use strings.Builder

Darien Raymond 7 years ago
parent
commit
122c3e7a5d
3 changed files with 50 additions and 12 deletions
  1. 16 8
      common/errors/errors.go
  2. 4 4
      common/serial/string.go
  3. 30 0
      common/serial/string_test.go

+ 16 - 8
common/errors/errors.go

@@ -4,6 +4,7 @@ package errors // import "v2ray.com/core/common/errors"
 import (
 	"os"
 	"reflect"
+	"strings"
 
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/serial"
@@ -41,21 +42,28 @@ func (err *Error) pkgPath() string {
 
 // Error implements error.Error().
 func (v *Error) Error() string {
-	msg := serial.Concat(v.message...)
-	if v.inner != nil {
-		msg += " > " + v.inner.Error()
+	builder := strings.Builder{}
+	for _, prefix := range v.prefix {
+		builder.WriteByte('[')
+		builder.WriteString(serial.ToString(prefix))
+		builder.WriteString("] ")
 	}
+
 	path := v.pkgPath()
 	if len(path) > 0 {
-		msg = path + ": " + msg
+		builder.WriteString(path)
+		builder.WriteString(": ")
 	}
 
-	var prefix string
-	for _, p := range v.prefix {
-		prefix += "[" + serial.ToString(p) + "] "
+	msg := serial.Concat(v.message...)
+	builder.WriteString(msg)
+
+	if v.inner != nil {
+		builder.WriteString(" > ")
+		builder.WriteString(v.inner.Error())
 	}
 
-	return prefix + msg
+	return builder.String()
 }
 
 // Inner implements hasInnerError.Inner()

+ 4 - 4
common/serial/string.go

@@ -28,11 +28,11 @@ func ToString(v interface{}) string {
 }
 
 func Concat(v ...interface{}) string {
-	values := make([]string, len(v))
-	for i, value := range v {
-		values[i] = ToString(value)
+	builder := strings.Builder{}
+	for _, value := range v {
+		builder.WriteString(ToString(value))
 	}
-	return strings.Join(values, "")
+	return builder.String()
 }
 
 func WriteString(s string) func([]byte) (int, error) {

+ 30 - 0
common/serial/string_test.go

@@ -26,3 +26,33 @@ func TestToString(t *testing.T) {
 		assert(ToString(c.Value), Equals, c.String)
 	}
 }
+
+func TestConcat(t *testing.T) {
+	testCases := []struct {
+		Input  []interface{}
+		Output string
+	}{
+		{
+			Input: []interface{}{
+				"a", "b",
+			},
+			Output: "ab",
+		},
+	}
+
+	for _, testCase := range testCases {
+		actual := Concat(testCase.Input...)
+		if actual != testCase.Output {
+			t.Error("Unexpected output: ", actual, " but want: ", testCase.Output)
+		}
+	}
+}
+
+func BenchmarkConcat(b *testing.B) {
+	input := []interface{}{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"}
+
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		_ = Concat(input...)
+	}
+}