将python代码转换为Go的性能不佳

将python代码转换为Go的性能不佳,go,Go,我试图学习Go的基础知识,并从转换Python中为Codibility编写的旧练习开始。对于大字符串,下面的代码在最坏情况下的执行速度约为四分之一秒。然而,当我将其转换为Go时,它没有通过大字符串的可编译性性能测试,并在6秒钟内执行 def solution(S): stack = [] for i in S: if len(stack) and stack[-1] == "(" and i == ")": stack.pop()

我试图学习Go的基础知识,并从转换Python中为Codibility编写的旧练习开始。对于大字符串,下面的代码在最坏情况下的执行速度约为四分之一秒。然而,当我将其转换为Go时,它没有通过大字符串的可编译性性能测试,并在6秒钟内执行

def solution(S):
    stack = []
    for i in S:
        if len(stack) and stack[-1] == "(" and i == ")":
            stack.pop()
            continue
        stack.append(i)

    return 1 if len(stack) == 0 else 0
执行

package solution

func Solution(S string) int {
    stack := make([]string, 0)
    for i := range S {
        s := string([]rune(S)[i])
        ln := len(stack)
        if ln > 0 && stack[ln-1] == "(" && s == ")" {
            stack = stack[:ln-1]
            continue
        }
        stack = append(stack, s)
    }
    if len(stack) == 0 {
        return 1
    } else {
        return 0 
    }
}
有人能分享一些关于我如何在Go中正确实现这一点的见解吗

这就是我想回答的问题

直接使用
[]字节将大大提高性能

正如Yandry Pozo的回答中提到的那样

您可以通过删除附加到堆栈并使用计数器来加快速度



您可以使用range对字符串进行迭代,请记住,您将得到一个字符串。您只需使用一个简单的计数器就可以节省时间,避免使用
append()
。其他注意事项如果在发现“')”且堆栈为空时提前返回,则算法可能会更快:

func Solution(S string) int {
    stack := make([]rune, len(S)+1)
    top := 0 // keep track of the stack top 

    for _, r := range S {
        if r == '(' {  // i got a '('
            stack[top] = r
            top++
        } else { // i got a ')'
            top--
            if top < 0 { // the stack is emtpy, early return
                return 0
            }
        }
    }

    if top == 0 {
        return 1    
    }
    return 0
}
func解决方案(S字符串)int{
堆栈:=生成([]符文,长度)+1)
top:=0//跟踪堆栈顶部
对于u,r:=范围S{
如果r=='('{//我得到了一个'('
堆栈[top]=r
顶++
}否则{//我得了一个''
顶--
如果top<0{//堆栈为emtpy,则提前返回
返回0
}
}
}
如果top==0{
返回1
}
返回0
}

代码中较慢的部分是这一行:

  s := string([]rune(S)[i])
要迭代字符串的字节,请执行以下操作:

for i, b := range []byte(s) {}
for i, c := range s {}
要迭代字符串的代码点,请执行以下操作:

for i, b := range []byte(s) {}
for i, c := range s {}

因此,只需为循环使用两个变量。

您可以直接使用文本
”(“
”)“
而不是变量
open
close
:因为它们将是非类型化的Go常量,在将它们与类型
byte
的值进行比较后,它们将得到真正的类型
byte
,并且由于它们的符文值在范围
[0..127]内
那就行了。顺便说一句,至少在Reference Go 1.7实现中,
中i,b:=range[]byte(s){}
的字节片将在源字符串的实际字节上创建,不涉及数据的复制。因此,我将使用直接
range[]byte(s)
与公认的答案或@yandry pozo的答案相结合。综上所述,这里与Python的主要区别在于字符串的表示和解释方式。请务必阅读它所链接的文章。