mirror of
https://github.com/golang/go
synced 2024-11-19 02:54:42 -07:00
runtime: add runtime.cmpstring and bytes.Compare
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>
This commit is contained in:
parent
a3a193c018
commit
e2543ef62c
@ -17,6 +17,8 @@ var compareTests = []struct {
|
||||
{[]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},
|
||||
@ -27,6 +29,7 @@ var compareTests = []struct {
|
||||
{[]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},
|
||||
|
@ -782,6 +782,57 @@ eq:
|
||||
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.
|
||||
|
@ -2,9 +2,9 @@
|
||||
// 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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user