]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: speed up eqstring
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 5 Feb 2015 01:31:37 +0000 (17:31 -0800)
committerJosh Bleecher Snyder <josharian@gmail.com>
Fri, 6 Feb 2015 18:51:00 +0000 (18:51 +0000)
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>
src/cmd/gc/walk.c
src/runtime/asm_386.s
src/runtime/asm_amd64.s
src/runtime/asm_amd64p32.s
src/runtime/asm_arm.s

index efb283a1b8f659982503574c13233048e92c3f26..89c465869160b9cf30331e8ce9811d89cdef22c8 100644 (file)
@@ -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);
index 49bba32ebe7ccede3a25af969113885f91f33393..58a0d502bde0e9490543a52291329a2110e756d7 100644 (file)
@@ -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
index f09e5ae250e16d4843310385da3b6b3b59b5a1ab..f6c1c5f6e6afc7a33ea67ef78120635b02f16ec0 100644 (file)
@@ -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
index 77355bb99870590caa1b5512e7cd0c7237b42341..f2324285a54fe436a9e42541cdd42984fba6bbfc 100644 (file)
@@ -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
index f3ce1a8f17bc85b91c60208e6ca404f1a4fcdafc..a7c6c20cfe8fb28c6c5022045d5a1eab5ecde754 100644 (file)
@@ -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.