Commit 135ef49f authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

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/3955Reviewed-by: 's avatarKeith Randall <khr@golang.org>
parent 15594df6
......@@ -1273,6 +1273,7 @@ walkexpr(Node **np, NodeList **init)
conv(n->right, types[TSTRING]));
// quick check of len before full compare for == or !=
// eqstring assumes that the lengths are equal
if(n->etype == OEQ) {
// len(left) == len(right) && eqstring(left, right)
r = nod(OANDAND, nod(OEQ, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
......
......@@ -1298,26 +1298,22 @@ eq:
RET
// 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
// equivalent Go code.
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 s2str+8(FP), DI
CMPL SI, DI
JEQ same
MOVL s1len+4(FP), BX
CALL runtime·memeqbody(SB)
MOVB AX, v+16(FP)
RET
same:
MOVB $1, v+16(FP)
RET
different:
MOVB $0, v+16(FP)
RET
TEXT bytes·Equal(SB),NOSPLIT,$0-25
MOVL a_len+4(FP), BX
......
......@@ -1262,26 +1262,22 @@ eq:
RET
// 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
// equivalent Go code.
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 s2str+16(FP), DI
CMPQ SI, DI
JEQ eq
MOVQ s1len+8(FP), BX
CALL runtime·memeqbody(SB)
MOVB AX, v+32(FP)
RET
eq:
MOVB $1, v+32(FP)
RET
noteq:
MOVB $0, v+32(FP)
RET
// a in SI
// b in DI
......
......@@ -704,26 +704,22 @@ eq:
RET
// 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
// equivalent Go code.
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 s2str+8(FP), DI
CMPL SI, DI
JEQ same
MOVL s1len+4(FP), BX
CALL runtime·memeqbody(SB)
MOVB AX, v+16(FP)
RET
same:
MOVB $1, v+16(FP)
RET
different:
MOVB $0, v+16(FP)
RET
// a in SI
// b in DI
......
......@@ -806,21 +806,18 @@ eq:
RET
// 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
// equivalent Go code.
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 s2str+8(FP), R3
MOVW $1, R8
MOVB R8, v+16(FP)
CMP R2, R3
RET.EQ
MOVW s1len+4(FP), R0
ADD R2, R0, R6
loop:
CMP R2, R6
......@@ -829,7 +826,8 @@ loop:
MOVBU.P 1(R3), R5
CMP R4, R5
BEQ loop
MOVB R7, v+16(FP)
MOVW $0, R8
MOVB R8, v+16(FP)
RET
// void setg_gcc(G*); set g called from gcc.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment