当前位置:网站首页>Several methods for deleting specified elements in Golang slices
Several methods for deleting specified elements in Golang slices
2022-07-31 21:12:00 【m0_67401228】
文章目录
Go 并没有提供删除切片元素专用的语法或函数,需要使用切片本身的特性来删除元素.
删除切片指定元素一般有如下几种方法,本文以 []int 为例给出具体实现.
1.截取法(修改原切片)
这里利用对 slice 的截取删除指定元素.注意删除时,后面的元素会前移,所以下标 i 应该左移一位.
// DeleteSlice1 删除指定元素.
func DeleteSlice1(a []int, elem int) []int {
for i := 0; i < len(a); i++ {
if a[i] == elem {
a = append(a[:i], a[i+1:]...)
i--
}
}
return a
}
2.拷贝法(不改原切片)
这种方法最容易理解,重新使用一个 slice,将要删除的元素过滤掉.缺点是需要开辟另一个 slice 的空间,优点是容易理解,而且不会修改原 slice.
// DeleteSlice2 删除指定元素.
func DeleteSlice2(a []int, elem int) []int {
tmp := make([]int, 0, len(a))
for _, v := range a {
if v != elem {
tmp = append(tmp, v)
}
}
return tmp
}
3.移位法(修改原切片)
3.1 方式一
利用一个下标 index,记录下一个有效元素应该在的位置.遍历所有元素,当遇到有效元素,将其移动到 index 且 index 加一.最终 index 的位置就是所有有效元素的下一个位置,最后做一个截取就行了.这种方法会修改原来的 slice.
该方法可以看成对第一种方法截取法的改进,因为每次指需移动一个元素,性能更加.
// DeleteSlice3 删除指定元素.
func DeleteSlice3(a []int, elem int) []int {
j := 0
for _, v := range a {
if v != elem {
a[j] = v
j++
}
}
return a[:j]
}
3.2 方式二
创建了一个 slice,但是共用原始 slice 的底层数组.这样也不需要额外分配内存空间,直接在原 slice 上进行修改.
// DeleteSlice4 删除指定元素.
func DeleteSlice4(a []int, elem int) []int {
tgt := a[:0]
for _, v := range a {
if v != elem {
tgt = append(tgt, v)
}
}
return tgt
}
4.性能对比
假设我们的切片有 0 和 1,我们要删除所有的 0.
这里分别对长度为 10、100、1000 的切片进行测试,来上下上面四种实现的性能差异.
生成切片函数如下:
func getSlice(n int) []int {
a := make([]int, 0, n)
for i := 0; i < n; i++ {
if i%2 == 0 {
a = append(a, 0)
continue
}
a = append(a, 1)
}
return a
}
基准测试代码如下:
func BenchmarkDeleteSlice1(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DeleteSlice1(getSlice(10), 0)
}
}
func BenchmarkDeleteSlice2(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DeleteSlice2(getSlice(10), 0)
}
}
func BenchmarkDeleteSlice3(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DeleteSlice3(getSlice(10), 0)
}
}
func BenchmarkDeleteSlice4(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DeleteSlice4(getSlice(10), 0)
}
}
测试结果如下:
原切片长度为 10:
go test -bench=. main/slice
goos: windows
goarch: amd64
pkg: main/slice
cpu: Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz
BenchmarkDeleteSlice1-8 17466486 65.07 ns/op
BenchmarkDeleteSlice2-8 14897282 85.22 ns/op
BenchmarkDeleteSlice3-8 21952129 50.78 ns/op
BenchmarkDeleteSlice4-8 22176390 54.68 ns/op
PASS
ok main/slice 5.427s
原切片长度为 100:
BenchmarkDeleteSlice1-8 1652146 762.1 ns/op
BenchmarkDeleteSlice2-8 2124237 578.4 ns/op
BenchmarkDeleteSlice3-8 3161318 359.9 ns/op
BenchmarkDeleteSlice4-8 2714158 423.7 ns/op
原切片长度为 1000:
BenchmarkDeleteSlice1-8 56067 21915 ns/op
BenchmarkDeleteSlice2-8 258662 5007 ns/op
BenchmarkDeleteSlice3-8 432049 2724 ns/op
BenchmarkDeleteSlice4-8 325194 3615 ns/op
5.小结
从基准测试结果来看,性能最佳的方法是移位法,其中又属第一种实现方式较佳.性能最差的也是最常用的方法是截取法.随着切片长度的增加,上面四种删除方式的性能差异会愈加明显.
实际使用时,我们可以根据不用场景来选择.如不能修改原切片使用拷贝法,可以修改原切片使用移位法中的第一种实现方式.
参考文献
golang删除slice中特定条件的元素,优化版
【Golang】slice删除元素的性能对比
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在.深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小.自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前.因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担.添加下方名片,即可获取全套学习资料哦
边栏推荐
- Several methods of mysql backup table
- leetcode: 6135. The longest ring in the graph [inward base ring tree + longest ring board + timestamp]
- Three.js入门
- Verilog implements a divide-by-9 with a duty cycle of 5/18
- Poker Game in C# -- Introduction and Code Implementation of Blackjack Rules
- Transfer Learning - Domain Adaptation
- find prime numbers up to n
- Efficient Concurrency: A Detailed Explanation of Synchornized's Lock Optimization
- 深度学习中的batch(batch size,full batch,mini batch, online learning)、iterations与epoch
- 全网一触即发,自媒体人的内容分发全能助手——融媒宝
猜你喜欢
flowable workflow all business concepts
A shortcut to search for specific character content in idea
财务盈利、偿债能力指标
21. Support Vector Machine - Introduction to Kernel Functions
Getting Started with Tkinter
Implementation of a sequence table
NVIDIA has begun testing graphics products with AD106 and AD107 GPU cores
Cache and Database Consistency Solutions
focus on!Haitai Fangyuan joins the "Personal Information Protection Self-discipline Convention"
OSPFv3的基本配置
随机推荐
Go1.18 upgrade function - Fuzz test from scratch in Go language
grep command written test questions
How can we improve the real yourself, become an excellent architect?
The whole network is on the verge of triggering, and the all-round assistant for content distribution from media people - Rongmeibao
Tkinter 入门之旅
Shell 脚本 快速入门到实战 -02
有一说一,外包公司到底值不值得去?
-xms -xmx(information value)
Implementation of a sequence table
leetcode 665. Non-decreasing Array 非递减数列(中等)
Made with Flutter and Firebase!counter application
One thing to say, is outsourcing company worth it?
Chapter VII
Realization of character makeup
Verilog implements a divide-by-9 with a duty cycle of 5/18
leetcode: 6135. The longest ring in the graph [inward base ring tree + longest ring board + timestamp]
Batch (batch size, full batch, mini batch, online learning), iterations and epochs in deep learning
Apache EventMesh 分布式事件驱动多运行时
linux view redis version command (linux view mysql version number)
深度学习中的batch(batch size,full batch,mini batch, online learning)、iterations与epoch