Update #10007
Implement runtime.cmpstring and bytes.Compare in asm for arm.
benchmark old ns/op new ns/op delta
BenchmarkCompareBytesEqual 254 91.4 -64.02%
BenchmarkCompareBytesToNil 41.5 37.6 -9.40%
BenchmarkCompareBytesEmpty 40.7 37.6 -7.62%
BenchmarkCompareBytesIdentical 255 96.3 -62.24%
BenchmarkCompareBytesSameLength 125 60.9 -51.28%
BenchmarkCompareBytesDifferentLength 133 60.9 -54.21%
BenchmarkCompareBytesBigUnaligned
17985879 5669706 -68.48%
BenchmarkCompareBytesBig
17097634 4926798 -71.18%
BenchmarkCompareBytesBigIdentical
16861941 4389206 -73.97%
benchmark old MB/s new MB/s speedup
BenchmarkCompareBytesBigUnaligned 58.30 184.95 3.17x
BenchmarkCompareBytesBig 61.33 212.83 3.47x
BenchmarkCompareBytesBigIdentical 62.19 238.90 3.84x
This is a collaboration between Josh Bleecher Snyder and myself.
Change-Id: Ib3944b8c410d0e12135c2ba9459bfe131df48edd
Reviewed-on: https://go-review.googlesource.com/8010
Reviewed-by: Keith Randall <khr@golang.org>
{[]byte("a"), []byte(""), 1},
{[]byte(""), []byte("a"), -1},
{[]byte("abc"), []byte("abc"), 0},
+ {[]byte("abd"), []byte("abc"), 1},
+ {[]byte("abc"), []byte("abd"), -1},
{[]byte("ab"), []byte("abc"), -1},
{[]byte("abc"), []byte("ab"), 1},
{[]byte("x"), []byte("ab"), 1},
{[]byte("abcdefgh"), []byte("abcdefgh"), 0},
{[]byte("abcdefghi"), []byte("abcdefghi"), 0},
{[]byte("abcdefghi"), []byte("abcdefghj"), -1},
+ {[]byte("abcdefghj"), []byte("abcdefghi"), 1},
// nil tests
{nil, nil, 0},
{[]byte(""), nil, 0},
MOVB R0, ret+8(FP)
RET
+TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
+ MOVW s1_base+0(FP), R2
+ MOVW s1_len+4(FP), R0
+ MOVW s2_base+8(FP), R3
+ MOVW s2_len+12(FP), R1
+ BL runtime·cmpbody(SB)
+ MOVW R8, ret+16(FP)
+ RET
+
+TEXT bytes·Compare(SB),NOSPLIT,$0-28
+ MOVW s1+0(FP), R2
+ MOVW s1+4(FP), R0
+ MOVW s2+12(FP), R3
+ MOVW s2+16(FP), R1
+ BL runtime·cmpbody(SB)
+ MOVW R8, ret+24(FP)
+ RET
+
+// On entry:
+// R0 is the length of s1
+// R1 is the length of s2
+// R2 points to the start of s1
+// R3 points to the start of s2
+//
+// On exit:
+// R8 is -1/0/+1
+// R5, R4, and R6 are clobbered
+TEXT runtime·cmpbody(SB),NOSPLIT,$-4-0
+ CMP R0, R1
+ MOVW R0, R6
+ MOVW.LT R1, R6 // R6 is min(R0, R1)
+
+ ADD R2, R6 // R2 is current byte in s1, R6 is last byte in s1 to compare
+loop:
+ CMP R2, R6
+ BEQ samebytes // all compared bytes were the same; compare lengths
+ MOVBU.P 1(R2), R4
+ MOVBU.P 1(R3), R5
+ CMP R4, R5
+ BEQ loop
+ // bytes differed
+ MOVW.LT $1, R8
+ MOVW.GT $-1, R8
+ RET
+samebytes:
+ CMP R0, R1
+ MOVW.LT $1, R8
+ MOVW.GT $-1, R8
+ MOVW.EQ $0, R8
+ RET
+
// eqstring tests whether two strings are equal.
// The compiler guarantees that strings passed
// to eqstring have equal length.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Routines that are implemented in assembly in asm_{amd64,386}.s
+// Routines that are implemented in assembly in asm_{amd64,386,arm}.s
-// +build arm arm64 ppc64 ppc64le
+// +build arm64 ppc64 ppc64le
package runtime