1
0
mirror of https://github.com/golang/go synced 2024-10-01 12:48:33 -06: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:
Dave Cheney 2015-03-24 09:37:10 +00:00
parent a3a193c018
commit e2543ef62c
3 changed files with 56 additions and 2 deletions

View File

@ -17,6 +17,8 @@ var compareTests = []struct {
{[]byte("a"), []byte(""), 1}, {[]byte("a"), []byte(""), 1},
{[]byte(""), []byte("a"), -1}, {[]byte(""), []byte("a"), -1},
{[]byte("abc"), []byte("abc"), 0}, {[]byte("abc"), []byte("abc"), 0},
{[]byte("abd"), []byte("abc"), 1},
{[]byte("abc"), []byte("abd"), -1},
{[]byte("ab"), []byte("abc"), -1}, {[]byte("ab"), []byte("abc"), -1},
{[]byte("abc"), []byte("ab"), 1}, {[]byte("abc"), []byte("ab"), 1},
{[]byte("x"), []byte("ab"), 1}, {[]byte("x"), []byte("ab"), 1},
@ -27,6 +29,7 @@ var compareTests = []struct {
{[]byte("abcdefgh"), []byte("abcdefgh"), 0}, {[]byte("abcdefgh"), []byte("abcdefgh"), 0},
{[]byte("abcdefghi"), []byte("abcdefghi"), 0}, {[]byte("abcdefghi"), []byte("abcdefghi"), 0},
{[]byte("abcdefghi"), []byte("abcdefghj"), -1}, {[]byte("abcdefghi"), []byte("abcdefghj"), -1},
{[]byte("abcdefghj"), []byte("abcdefghi"), 1},
// nil tests // nil tests
{nil, nil, 0}, {nil, nil, 0},
{[]byte(""), nil, 0}, {[]byte(""), nil, 0},

View File

@ -782,6 +782,57 @@ eq:
MOVB R0, ret+8(FP) MOVB R0, ret+8(FP)
RET 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. // eqstring tests whether two strings are equal.
// The compiler guarantees that strings passed // The compiler guarantees that strings passed
// to eqstring have equal length. // to eqstring have equal length.

View File

@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // 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 package runtime