mirror of
https://github.com/golang/go
synced 2024-11-18 18:04:46 -07:00
runtime: speed up eqstring
eqstring does not need to check the length of the strings. 6g benchmark old ns/op new ns/op delta BenchmarkCompareStringEqual 7.03 6.14 -12.66% BenchmarkCompareStringIdentical 3.36 3.04 -9.52% 5g benchmark old ns/op new ns/op delta BenchmarkCompareStringEqual 238 232 -2.52% BenchmarkCompareStringIdentical 90.8 80.7 -11.12% The equivalent PPC changes are in a separate commit because I don't have the hardware to test them. Change-Id: I292874324b9bbd9d24f57a390cfff8b550cdd53c Reviewed-on: https://go-review.googlesource.com/3955 Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
15594df6b4
commit
135ef49fde
@ -1273,6 +1273,7 @@ walkexpr(Node **np, NodeList **init)
|
|||||||
conv(n->right, types[TSTRING]));
|
conv(n->right, types[TSTRING]));
|
||||||
|
|
||||||
// quick check of len before full compare for == or !=
|
// quick check of len before full compare for == or !=
|
||||||
|
// eqstring assumes that the lengths are equal
|
||||||
if(n->etype == OEQ) {
|
if(n->etype == OEQ) {
|
||||||
// len(left) == len(right) && eqstring(left, right)
|
// len(left) == len(right) && eqstring(left, right)
|
||||||
r = nod(OANDAND, nod(OEQ, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
|
r = nod(OANDAND, nod(OEQ, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
|
||||||
|
@ -1298,26 +1298,22 @@ eq:
|
|||||||
RET
|
RET
|
||||||
|
|
||||||
// eqstring tests whether two strings are equal.
|
// eqstring tests whether two strings are equal.
|
||||||
|
// The compiler guarantees that strings passed
|
||||||
|
// to eqstring have equal length.
|
||||||
// See runtime_test.go:eqstring_generic for
|
// See runtime_test.go:eqstring_generic for
|
||||||
// equivalent Go code.
|
// equivalent Go code.
|
||||||
TEXT runtime·eqstring(SB),NOSPLIT,$0-17
|
TEXT runtime·eqstring(SB),NOSPLIT,$0-17
|
||||||
MOVL s1len+4(FP), AX
|
|
||||||
MOVL s2len+12(FP), BX
|
|
||||||
CMPL AX, BX
|
|
||||||
JNE different
|
|
||||||
MOVL s1str+0(FP), SI
|
MOVL s1str+0(FP), SI
|
||||||
MOVL s2str+8(FP), DI
|
MOVL s2str+8(FP), DI
|
||||||
CMPL SI, DI
|
CMPL SI, DI
|
||||||
JEQ same
|
JEQ same
|
||||||
|
MOVL s1len+4(FP), BX
|
||||||
CALL runtime·memeqbody(SB)
|
CALL runtime·memeqbody(SB)
|
||||||
MOVB AX, v+16(FP)
|
MOVB AX, v+16(FP)
|
||||||
RET
|
RET
|
||||||
same:
|
same:
|
||||||
MOVB $1, v+16(FP)
|
MOVB $1, v+16(FP)
|
||||||
RET
|
RET
|
||||||
different:
|
|
||||||
MOVB $0, v+16(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT bytes·Equal(SB),NOSPLIT,$0-25
|
TEXT bytes·Equal(SB),NOSPLIT,$0-25
|
||||||
MOVL a_len+4(FP), BX
|
MOVL a_len+4(FP), BX
|
||||||
|
@ -1262,26 +1262,22 @@ eq:
|
|||||||
RET
|
RET
|
||||||
|
|
||||||
// eqstring tests whether two strings are equal.
|
// eqstring tests whether two strings are equal.
|
||||||
|
// The compiler guarantees that strings passed
|
||||||
|
// to eqstring have equal length.
|
||||||
// See runtime_test.go:eqstring_generic for
|
// See runtime_test.go:eqstring_generic for
|
||||||
// equivalent Go code.
|
// equivalent Go code.
|
||||||
TEXT runtime·eqstring(SB),NOSPLIT,$0-33
|
TEXT runtime·eqstring(SB),NOSPLIT,$0-33
|
||||||
MOVQ s1len+8(FP), AX
|
|
||||||
MOVQ s2len+24(FP), BX
|
|
||||||
CMPQ AX, BX
|
|
||||||
JNE noteq
|
|
||||||
MOVQ s1str+0(FP), SI
|
MOVQ s1str+0(FP), SI
|
||||||
MOVQ s2str+16(FP), DI
|
MOVQ s2str+16(FP), DI
|
||||||
CMPQ SI, DI
|
CMPQ SI, DI
|
||||||
JEQ eq
|
JEQ eq
|
||||||
|
MOVQ s1len+8(FP), BX
|
||||||
CALL runtime·memeqbody(SB)
|
CALL runtime·memeqbody(SB)
|
||||||
MOVB AX, v+32(FP)
|
MOVB AX, v+32(FP)
|
||||||
RET
|
RET
|
||||||
eq:
|
eq:
|
||||||
MOVB $1, v+32(FP)
|
MOVB $1, v+32(FP)
|
||||||
RET
|
RET
|
||||||
noteq:
|
|
||||||
MOVB $0, v+32(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// a in SI
|
// a in SI
|
||||||
// b in DI
|
// b in DI
|
||||||
|
@ -704,26 +704,22 @@ eq:
|
|||||||
RET
|
RET
|
||||||
|
|
||||||
// eqstring tests whether two strings are equal.
|
// eqstring tests whether two strings are equal.
|
||||||
|
// The compiler guarantees that strings passed
|
||||||
|
// to eqstring have equal length.
|
||||||
// See runtime_test.go:eqstring_generic for
|
// See runtime_test.go:eqstring_generic for
|
||||||
// equivalent Go code.
|
// equivalent Go code.
|
||||||
TEXT runtime·eqstring(SB),NOSPLIT,$0-17
|
TEXT runtime·eqstring(SB),NOSPLIT,$0-17
|
||||||
MOVL s1len+4(FP), AX
|
|
||||||
MOVL s2len+12(FP), BX
|
|
||||||
CMPL AX, BX
|
|
||||||
JNE different
|
|
||||||
MOVL s1str+0(FP), SI
|
MOVL s1str+0(FP), SI
|
||||||
MOVL s2str+8(FP), DI
|
MOVL s2str+8(FP), DI
|
||||||
CMPL SI, DI
|
CMPL SI, DI
|
||||||
JEQ same
|
JEQ same
|
||||||
|
MOVL s1len+4(FP), BX
|
||||||
CALL runtime·memeqbody(SB)
|
CALL runtime·memeqbody(SB)
|
||||||
MOVB AX, v+16(FP)
|
MOVB AX, v+16(FP)
|
||||||
RET
|
RET
|
||||||
same:
|
same:
|
||||||
MOVB $1, v+16(FP)
|
MOVB $1, v+16(FP)
|
||||||
RET
|
RET
|
||||||
different:
|
|
||||||
MOVB $0, v+16(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// a in SI
|
// a in SI
|
||||||
// b in DI
|
// b in DI
|
||||||
|
@ -806,21 +806,18 @@ eq:
|
|||||||
RET
|
RET
|
||||||
|
|
||||||
// eqstring tests whether two strings are equal.
|
// eqstring tests whether two strings are equal.
|
||||||
|
// The compiler guarantees that strings passed
|
||||||
|
// to eqstring have equal length.
|
||||||
// See runtime_test.go:eqstring_generic for
|
// See runtime_test.go:eqstring_generic for
|
||||||
// equivalent Go code.
|
// equivalent Go code.
|
||||||
TEXT runtime·eqstring(SB),NOSPLIT,$-4-17
|
TEXT runtime·eqstring(SB),NOSPLIT,$-4-17
|
||||||
MOVW s1len+4(FP), R0
|
|
||||||
MOVW s2len+12(FP), R1
|
|
||||||
MOVW $0, R7
|
|
||||||
CMP R0, R1
|
|
||||||
MOVB.NE R7, v+16(FP)
|
|
||||||
RET.NE
|
|
||||||
MOVW s1str+0(FP), R2
|
MOVW s1str+0(FP), R2
|
||||||
MOVW s2str+8(FP), R3
|
MOVW s2str+8(FP), R3
|
||||||
MOVW $1, R8
|
MOVW $1, R8
|
||||||
MOVB R8, v+16(FP)
|
MOVB R8, v+16(FP)
|
||||||
CMP R2, R3
|
CMP R2, R3
|
||||||
RET.EQ
|
RET.EQ
|
||||||
|
MOVW s1len+4(FP), R0
|
||||||
ADD R2, R0, R6
|
ADD R2, R0, R6
|
||||||
loop:
|
loop:
|
||||||
CMP R2, R6
|
CMP R2, R6
|
||||||
@ -829,7 +826,8 @@ loop:
|
|||||||
MOVBU.P 1(R3), R5
|
MOVBU.P 1(R3), R5
|
||||||
CMP R4, R5
|
CMP R4, R5
|
||||||
BEQ loop
|
BEQ loop
|
||||||
MOVB R7, v+16(FP)
|
MOVW $0, R8
|
||||||
|
MOVB R8, v+16(FP)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// void setg_gcc(G*); set g called from gcc.
|
// void setg_gcc(G*); set g called from gcc.
|
||||||
|
Loading…
Reference in New Issue
Block a user