使用字节切片(或数组)时,优化Go(Golang)代码的几个技巧有哪些?

huangapple go评论97阅读模式
英文:

What are a few tips for optimizing go (golang) code when using slices (or arrays) of bytes?

问题

我在想,一个初学者在编写(无意中慢速的)Go代码时可能会遇到哪些常见陷阱。

1)首先,我知道在Python中进行字符串拼接可能会很慢(或者过去可能很慢),在Go中当尝试将一个元素添加到字符串中时是否也是如此?就像"hello"+"World"这样。

2)另一个问题是,我经常发现自己需要用一系列更多的字节来扩展切片(而不是每次扩展一个字节)。我有一种"不太好的"方法来追加它,就像这样:

newStr := string(arrayOfBytes) + string(newBytesToAppend)

这种方式比只是像下面这样做慢吗?

for _, b := range newBytesToAppend{
    arrayOfBytes = append(arrayOfBytes, b)
}

或者有没有更好的方法来将整个切片追加到其他切片中,或者可能有内置的方法?对我来说,这似乎有点奇怪,我甚至需要编写自己的扩展函数(甚至对其进行基准测试)。

此外,有时我不得不遍历字节切片的每个元素,并为了可读性,将当前字节的类型更改为字符串。就像这样:

for _, b := range newBytesToAppend{
    c := string(b)
    //对c进行更多逻辑处理
    logic(c) //逻辑处理
}

3)我想知道,在Go中转换类型是否很慢(特别是在字符串和数组之间),以及这是否可能是使代码变慢的因素之一。顺便说一句,有时我(非常)经常更改类型(转换为字符串),几乎每次迭代都要更改。

但更一般地说,我试图在网络上搜索常见的使Go代码变慢的原因,并试图进行更改以避免这种情况(但运气不太好)。我非常清楚这取决于应用程序,但我想知道是否有任何关于通常使"初学者"的Go代码变慢的"专家"建议。

4)我能想到的最后一件事是,有时我事先知道切片的长度,所以我可以使用具有固定长度的数组。这会改变什么吗?

5)我还创建了自己的类型,例如:

type Num int

或者

type Name string

这些会影响性能吗?

6)是否有一般的启发式列表,可以用来优化Go代码?例如,解引用是否是一个问题,就像在C中一样?

英文:

I waw wondering what could be some of the common pitfalls that a novice go programmer could fall in when writing (unintentionally slow go code).

  1. First, I know that in python doing string concatenation can be (or used to be expensive), is that the same in go when trying to add one element to a string? As in "hello"+"World".

  2. The other issue is that I find myself very often having to extend my slice with a list of more bytes (rather than 1 byte at a time). I have a "dirty" way of appending it by doing the following:

newStr := string(arrayOfBytes) + string(newBytesToAppend)

Is that way slower than just doing something like?

for _, b := range newBytesToAppend{
    arrayOfBytes = append(arrayOfBytes, b)
}

Or is there a better way to append whole slices to other slices or maybe a built in way? It just seems to me a little odd that I would even have to write my own extend function (or even benchmark it)

Also, sometimes I end up having to loop through every element of the byte slice and for readability, I change the type of that current byte to a string. As in:

for _, b := range newBytesToAppend{
    c := string(b)
    //some more logic on c
    logic(c) //logic
}
  1. I was wondering, if converting types in go is expensive (specially between string to arrays) and if that might be one of the factors that might be making the code slow. Btw, sometimes I change types (to strings) very often, nearly every iteration.

But more generally, I was trying to search for the web a list of hints of what often are things that makes go code slow and was trying to change it so that it wouldn't (but didn't have that much luck). I am very much aware that this depends from application to application, but was wondering if there are any "expert" advice on what usually makes "novice" go code slow.

  1. The last thing I can think of is, that sometimes I do know in advance the length of the slice, so I could just use arrays with fixed length. Could that change anything?

  2. I have also made my own types as in:

    type Num int

or

type Name string

Do those hinder performance?

  1. Is there a general list of heuristic to watch out in go for code optimization? For example, is dereferencing a problem as it can be in C?

答案1

得分: 3

使用bytes.Buffer / Buffer.Write,它会自动调整内部切片的大小,这是管理多个[]byte的最高效方式。

至于第二个问题,使用简单的基准测试很容易回答。

英文:

Use bytes.Buffer / Buffer.Write, it handles re-sizing the internal slice for you and it's by far the most effiecent way to manage multiple []bytes.

About the 2nd question, it's rather easy to answer that using a simple benchmark.

huangapple
  • 本文由 发表于 2014年8月12日 08:42:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/25254553.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定