当前位置:网站首页>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开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担.添加下方名片,即可获取全套学习资料哦
边栏推荐
- Basic Grammar Introduction of Carbon Tutorial (Tutorial)
- Shell 脚本 快速入门到实战 -02
- ResNet的基础:残差块的原理
- rj45对接头千兆(百兆以太网接口定义)
- uni-app中的renderjs使用
- [Intensive reading of the paper] iNeRF
- 每月一书(202207):《Swift编程权威指南》
- grep command written test questions
- Teach you how to deploy Nestjs projects
- Book of the Month (202207): The Definitive Guide to Swift Programming
猜你喜欢

高通cDSP简单编程例子(实现查询高通cDSP使用率、签名),RK3588 npu使用率查询
![leetcode: 6135. The longest ring in the graph [inward base ring tree + longest ring board + timestamp]](/img/91/284de3dcbb8d143d85775b314dd41c.png)
leetcode: 6135. The longest ring in the graph [inward base ring tree + longest ring board + timestamp]

NVIDIA has begun testing graphics products with AD106 and AD107 GPU cores

【论文精读】iNeRF

【PIMF】OpenHarmony 啃论文俱乐部—盘点开源鸿蒙三方库【3】

Financial profitability and solvency indicators

MATLAB program design and application 2.4 Common internal functions of MATLAB

OSPFv3的基本配置

Count characters in UTF-8 string function

顺序表的实现
随机推荐
GAC Honda Safety Experience Camp: "Danger" is the best teacher
Count characters in UTF-8 string function
focus on!Haitai Fangyuan joins the "Personal Information Protection Self-discipline Convention"
利用反射实现一个管理对象信息的简单框架
Financial profitability and solvency indicators
Implementing a Simple Framework for Managing Object Information Using Reflection
【AcWing】第 62 场周赛 【2022.07.30】
rj45对接头千兆(百兆以太网接口定义)
Made with Flutter and Firebase!counter application
UVM RAL model and built-in seq
如何才能真正的提高自己,成为一名出色的架构师?
&lt;artifactId&gt;ojdbc8&lt;/artifactId&gt;「建议收藏」
Three.js入门
uni-app中的renderjs使用
微信小程序的路由拦截
Three. Introduction to js
架构实战营模块八作业
【AcWing】The 62nd Weekly Match 【2022.07.30】
What is Thymeleaf?How to use.
21. Support Vector Machine - Introduction to Kernel Functions