Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimized b2s function #1483

Merged
merged 1 commit into from
Feb 8, 2023
Merged

optimized b2s function #1483

merged 1 commit into from
Feb 8, 2023

Conversation

orangesobeautiful
Copy link
Contributor

New function use unsafe.SliceData to get pointer of the argument 'b', it does not need to check len(b) and use less instructions in ASM code.

Environment: go1.20.0 linux/amd64
(The go code)

func b2s(b []byte) string {
	if len(b) == 0 {
		return ""
	}

	return unsafe.String(&b[0], len(b))
}

func b2sfast(b []byte) string {
	return unsafe.String(unsafe.SliceData(b), len(b))
}

(In ASM)

<unlinkable>.b2s STEXT size=108 args=0x18 locals=0x8 funcid=0x0 align=0x0
        0x0000 00000 (b2s_new.go:8)     TEXT    <unlinkable>.b2s(SB), ABIInternal, $8-24
        0x0000 00000 (b2s_new.go:8)     CMPQ    SP, 16(R14)
        0x0004 00004 (b2s_new.go:8)     PCDATA  $0, $-2
        0x0004 00004 (b2s_new.go:8)     JLS     71
        0x0006 00006 (b2s_new.go:8)     PCDATA  $0, $-1
        0x0006 00006 (b2s_new.go:8)     SUBQ    $8, SP
        0x000a 00010 (b2s_new.go:8)     MOVQ    BP, (SP)
        0x000e 00014 (b2s_new.go:8)     LEAQ    (SP), BP
        0x0012 00018 (b2s_new.go:8)     MOVQ    AX, <unlinkable>.b+16(FP)
        0x0017 00023 (b2s_new.go:8)     FUNCDATA        $0, gclocals·wgcWObbY2HYnK2SU/U22lA==(SB)
        0x0017 00023 (b2s_new.go:8)     FUNCDATA        $1, gclocals·J5F+7Qw7O7ve2QcWC7DpeQ==(SB)
        0x0017 00023 (b2s_new.go:8)     FUNCDATA        $5, <unlinkable>.b2s.arginfo1(SB)
        0x0017 00023 (b2s_new.go:8)     FUNCDATA        $6, <unlinkable>.b2s.argliveinfo(SB)
        0x0017 00023 (b2s_new.go:8)     PCDATA  $3, $1
-       0x0017 00023 (b2s_new.go:9)     TESTQ   BX, BX
-       0x001a 00026 (b2s_new.go:9)     JEQ     51
        0x001c 00028 (b2s_new.go:13)    MOVQ    AX, CX
        0x001f 00031 (b2s_new.go:13)    NEGQ    AX
        0x0022 00034 (b2s_new.go:13)    CMPQ    BX, AX
        0x0025 00037 (b2s_new.go:13)    JHI     65
        0x0027 00039 (b2s_new.go:13)    MOVQ    CX, AX
        0x002a 00042 (b2s_new.go:13)    MOVQ    (SP), BP
        0x002e 00046 (b2s_new.go:13)    ADDQ    $8, SP
        0x0032 00050 (b2s_new.go:13)    RET
-       0x0033 00051 (b2s_new.go:10)    XORL    AX, AX
-       0x0035 00053 (b2s_new.go:10)    XORL    BX, BX
-       0x0037 00055 (b2s_new.go:10)    MOVQ    (SP), BP
-       0x003b 00059 (b2s_new.go:10)    ADDQ    $8, SP
-       0x003f 00063 (b2s_new.go:10)    NOP
-       0x0040 00064 (b2s_new.go:10)    RET
        0x0041 00065 (b2s_new.go:13)    PCDATA  $1, $1
        0x0041 00065 (b2s_new.go:13)    CALL    runtime.panicunsafestringlen(SB)
        0x0046 00070 (b2s_new.go:13)    XCHGL   AX, AX
        0x0047 00071 (b2s_new.go:13)    NOP
        0x0047 00071 (b2s_new.go:8)     PCDATA  $1, $-1
        0x0047 00071 (b2s_new.go:8)     PCDATA  $0, $-2
        0x0047 00071 (b2s_new.go:8)     MOVQ    AX, 8(SP)
        0x004c 00076 (b2s_new.go:8)     MOVQ    BX, 16(SP)
        0x0051 00081 (b2s_new.go:8)     MOVQ    CX, 24(SP)
        0x0056 00086 (b2s_new.go:8)     CALL    runtime.morestack_noctxt(SB)
        0x005b 00091 (b2s_new.go:8)     MOVQ    8(SP), AX
        0x0060 00096 (b2s_new.go:8)     MOVQ    16(SP), BX
        0x0065 00101 (b2s_new.go:8)     MOVQ    24(SP), CX
        0x006a 00106 (b2s_new.go:8)     PCDATA  $0, $-1
        0x006a 00106 (b2s_new.go:8)     JMP     0

<unlinkable>.b2sfast STEXT size=92 args=0x18 locals=0x8 funcid=0x0 align=0x0
        0x0000 00000 (b2s_new.go:16)    TEXT    <unlinkable>.b2sfast(SB), ABIInternal, $8-24
        0x0000 00000 (b2s_new.go:16)    CMPQ    SP, 16(R14)
        0x0004 00004 (b2s_new.go:16)    PCDATA  $0, $-2
        0x0004 00004 (b2s_new.go:16)    JLS     55
        0x0006 00006 (b2s_new.go:16)    PCDATA  $0, $-1
        0x0006 00006 (b2s_new.go:16)    SUBQ    $8, SP
        0x000a 00010 (b2s_new.go:16)    MOVQ    BP, (SP)
        0x000e 00014 (b2s_new.go:16)    LEAQ    (SP), BP
        0x0012 00018 (b2s_new.go:16)    MOVQ    AX, <unlinkable>.b+16(FP)
        0x0017 00023 (b2s_new.go:16)    FUNCDATA        $0, gclocals·wgcWObbY2HYnK2SU/U22lA==(SB)
        0x0017 00023 (b2s_new.go:16)    FUNCDATA        $1, gclocals·J5F+7Qw7O7ve2QcWC7DpeQ==(SB)
        0x0017 00023 (b2s_new.go:16)    FUNCDATA        $5, <unlinkable>.b2sfast.arginfo1(SB)
        0x0017 00023 (b2s_new.go:16)    FUNCDATA        $6, <unlinkable>.b2sfast.argliveinfo(SB)
        0x0017 00023 (b2s_new.go:16)    PCDATA  $3, $1
        0x0017 00023 (b2s_new.go:17)    MOVQ    AX, CX
        0x001a 00026 (b2s_new.go:17)    NEGQ    AX
+       0x001d 00029 (b2s_new.go:17)    NOP
        0x0020 00032 (b2s_new.go:17)    CMPQ    BX, AX
        0x0023 00035 (b2s_new.go:17)    JHI     49
        0x0025 00037 (b2s_new.go:17)    MOVQ    CX, AX
        0x0028 00040 (b2s_new.go:17)    MOVQ    (SP), BP
        0x002c 00044 (b2s_new.go:17)    ADDQ    $8, SP
        0x0030 00048 (b2s_new.go:17)    RET
        0x0031 00049 (b2s_new.go:17)    PCDATA  $1, $1
        0x0031 00049 (b2s_new.go:17)    CALL    runtime.panicunsafestringlen(SB)
        0x0036 00054 (b2s_new.go:17)    XCHGL   AX, AX
        0x0037 00055 (b2s_new.go:17)    NOP
        0x0037 00055 (b2s_new.go:16)    PCDATA  $1, $-1
        0x0037 00055 (b2s_new.go:16)    PCDATA  $0, $-2
        0x0037 00055 (b2s_new.go:16)    MOVQ    AX, 8(SP)
        0x003c 00060 (b2s_new.go:16)    MOVQ    BX, 16(SP)
        0x0041 00065 (b2s_new.go:16)    MOVQ    CX, 24(SP)
        0x0046 00070 (b2s_new.go:16)    CALL    runtime.morestack_noctxt(SB)
        0x004b 00075 (b2s_new.go:16)    MOVQ    8(SP), AX
        0x0050 00080 (b2s_new.go:16)    MOVQ    16(SP), BX
        0x0055 00085 (b2s_new.go:16)    MOVQ    24(SP), CX
        0x005a 00090 (b2s_new.go:16)    PCDATA  $0, $-1
        0x005a 00090 (b2s_new.go:16)    JMP     0

@erikdubbelboer erikdubbelboer merged commit b0fe6f0 into valyala:master Feb 8, 2023
@erikdubbelboer
Copy link
Collaborator

Thanks, good catch!

@stokito
Copy link
Contributor

stokito commented Feb 21, 2023

Should we make the same change for EasyJson? mailru/easyjson@a209843

I extracted the s2b and b2s functions to a separate micro dependency to use in my project
https://github.com/stokito/go-str2bytes
Maybe instead we may send a PR to the EasyJson to use the dependency?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants