当前位置:网站首页>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开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担.添加下方名片,即可获取全套学习资料哦
边栏推荐
- MySQL---Basic select statement
- What's wrong with the sql syntax in my sql
- Chapter Six
- The whole network is on the verge of triggering, and the all-round assistant for content distribution from media people - Rongmeibao
- Three. Introduction to js
- linux查看redis版本命令(linux查看mysql版本号)
- &lt;artifactId&gt;ojdbc8&lt;/artifactId&gt;「建议收藏」
- BM5 合并k个已排序的链表
- spark reports an error OutOfMemory "recommended collection"
- Qualcomm cDSP simple programming example (to query Qualcomm cDSP usage, signature), RK3588 npu usage query
猜你喜欢

Three.js入门

Realize serial port receiving data based on STM32 ring queue

财务盈利、偿债能力指标
Cache and Database Consistency Solutions

How programmers learn open source projects, this article tells you

【公开课预告】:超分辨率技术在视频画质增强领域的研究与应用

focus on!Haitai Fangyuan joins the "Personal Information Protection Self-discipline Convention"

手把手教你学会部署Nestjs项目

C# 之 扑克游戏 -- 21点规则介绍和代码实现

嵌入式开发没有激情了,正常吗?
随机推荐
Redis Overview: Talk to the interviewer all night long about Redis caching, persistence, elimination mechanism, sentinel, and the underlying principles of clusters!...
【愚公系列】2022年07月 Go教学课程 025-递归函数
Getting Started with Tkinter
多线程之锁
[Open class preview]: Research and application of super-resolution technology in the field of video image quality enhancement
21. Support Vector Machine - Introduction to Kernel Functions
sqlite3简单操作
每月一书(202207):《Swift编程权威指南》
npm 更改为淘宝镜像的方法[通俗易懂]
Poker Game in C# -- Introduction and Code Implementation of Blackjack Rules
高通cDSP简单编程例子(实现查询高通cDSP使用率、签名),RK3588 npu使用率查询
Chapter Six
MATLAB program design and application 2.4 Common internal functions of MATLAB
1161. 最大层内元素和 : 层序遍历运用题
Financial profitability and solvency indicators
rj45对接头千兆(百兆以太网接口定义)
SiC MOSFET的短路特性及保护
手把手教你学会部署Nestjs项目
How programmers learn open source projects, this article tells you
Three. Introduction to js