核心语言中的字符串比较

时间:2016-06-10 17:15:39

标签: optimization go

采用这种简单的比较loopValue == "Firstname",以下陈述是真的吗?

  

如果检查第一个char的内部操作数与比较字符串不匹配,则会提前中止

因此,原始格式loopValue"Firstname"都是[]byte。它会这样的数组类似于回真循环的真相:

someInspectionFunc(loopValue, "Firstname", func(charA, charB) {
    return charA == charB
})

...让它继续前进直到它碰到false并检查iterations的数量是否等于它们的长度。还先检查长度吗?

if len(loopValue) != len("Firstname") {
    return false
}

我无法在GitHub上的go源代码中找到解释,因为它有点高于我。

我问这个的原因是因为我正在进行大数据处理,并且正在进行基准测试并执行cpu,内存和分配pprof以便从流程中挤出更多的数据。从那个过程开始,它让我想到Go(也是一般的C)会在幕后做到这一点。这完全是在汇编级别上还是已经在本机Go代码中进行了比较(有点像上面的代码片段中描绘的那样)?

如果我太模糊或错过了什么,请告诉我。谢谢

更新

当我在firstCharater的大字符串中进行json匹配时,在真正比较之前我得到了关于100k重度条目的3.7%基准增益:

<some irrelevant inspection code>.. v[0] == firstChar && v == lookFor {
    // Match found when it reaches here
}

上面的代码(尤其是长字符串)比v == lookFor更快。

1 个答案:

答案 0 :(得分:6)

该功能在程序集中处理。 amd64版本是:

TEXT runtime·eqstring(SB),NOSPLIT,$0-33
    MOVQ    s1str+0(FP), SI
    MOVQ    s2str+16(FP), DI
    CMPQ    SI, DI
    JEQ eq
    MOVQ    s1len+8(FP), BX
    LEAQ    v+32(FP), AX
    JMP runtime·memeqbody(SB)
eq:
    MOVB    $1, v+32(FP)
    RET

编译器的工作是确保字符串在调用之前具有相同的长度。 (runtime·memeqbody函数实际上是优化内存比较发生的地方,但可能不需要在此处发布全文)

等效的Go代码为:

func eqstring_generic(s1, s2 string) bool {
    if len(s1) != len(s2) {
        return false
    }
    for i := 0; i < len(s1); i++ {
        if s1[i] != s2[i] {
            return false
        }
    }
    return true
}