我有这个功能。输入是
uint8
字节的切片。此函数在每个 255
字节后插入一个等于 0xff
或 3
值的新字节。
func ApplyAlpha(pix []uint8) []uint8 {
l := 0
for i := 0; i < len(pix); i++ {
l++
if l%3 == 0 && i+1 < len(pix) {
// Insert alpha at the current position
pix = append(pix[:i+1], append([]byte{255}, pix[i+1:]...)...)
i++
}
}
return pix
}
为了优化功能,我可以这样重写:
func ApplyAlpha(pix []uint8) []uint8 {
newPix := make([]uint8, len(pix)/3*4, len(pix)/3*4)
l := 0
for i := 0; i < len(pix); i++ {
newPix[l] = pix[i]
l++
if (i+1)%3 == 0 {
// Insert alpha at the current position
newPix[l] = 255
l++
}
}
pix = newPix
return pix
}
第一种实现方式和第二种实现方式都有缺点:
append
调用,第一次实现的成本很高。有什么我不知道的技巧或解决方法吗?进一步优化实施?
正如@PaulHankin 评论的那样:
最佳方法是确保
从一开始就具有足够的pix
以允许调整大小就地工作,然后您可以就地调整大小并将字节移动到正确的位置(例如:通过向后迭代通过切片)。cap
也许我们可以通过以下方式进一步优化:
func ApplyAlpha(pix []uint8) []uint8 {
newLen := len(pix) / 3 * 4
if newLen <= cap(pix) {
pix = pix[:newLen]
} else {
pix = append(pix, make([]uint8, newLen-len(pix))...)
}
// number of original pixels (without the alpha channel)
l := len(pix)/4*3 - 1
// Work backward to avoid overwriting data
for i := len(pix) - 1; i >= 0; i-- {
if (i+1)%4 == 0 {
pix[i] = 255
} else {
pix[i] = pix[l]
l--
}
}
return pix
}