当前位置: 首页 > news >正文

建设工程信息网为官方网站搜索引擎营销

建设工程信息网为官方网站,搜索引擎营销,ps外包网站,微信小程序商家版背景 ​ 如果让我评选最伟大的数据结构,在我心中答案只有两个,数组和哈希表,这两个是我的程序的重要组成部分,同时也是我饭碗的重要组成部分。slice和map简洁明了的API很容易让我们有一种他们提供了无限大的空间,可以…

背景

​ 如果让我评选最伟大的数据结构,在我心中答案只有两个,数组和哈希表,这两个是我的程序的重要组成部分,同时也是我饭碗的重要组成部分。slice和map简洁明了的API很容易让我们有一种他们提供了无限大的空间,可以容纳无限多的数据。然而,我们内心都有一面明镜,知道他们这些岁月静好的背后是通过扩容操作替我们负重前行。在nutsdb有slice和map来构建关键的数据结构或者处理数据,为了探究slice和map的使用对性能有没有影响,有多大影响,由此评估需不需要对这两个数据结构的使用方式进行优化。于是对slice和map扩容对性能的影响这个问题做了一些探究。总结出了一些文章。这是这个系列的第一篇文章。对slice扩容对性能的影响的研究。分享给大家。

1. Slice扩容对性能的影响

Slice是Go提供给我们的数据结构,基本上也是我们开发中最常用的数据结构了,在开发中使用过程一般是下面这样:

func TestSliceBaseUsage(t *testing.T) {var slice []intslice = append(slice, 1, 2, 3)
}func TestSizedSliceBaseUsage(t *testing.T) {slice := make([]int, 10)slice = append(slice, 1, 2, 3)
}

第一种用法就是不指定切片的容量,用到哪里是哪里,第二种就是指定了容量,先申请一片空间,等用到了一定程度再继续扩容。那么他们两个之间到底有怎样的差异呢?我们来看看下面这段Benchmark测试。

func BenchmarkSlickGrow(b *testing.B) {// 要测试的切片长度var lengths = []int{1000, 10 * 1000, 100 * 1000, 1000 * 1000}for _, length := range lengths {// 直接申请空间的切片 性能测试nameOfNotGrowBM := fmt.Sprintf("test_slice_not_grow_%d", length)b.Run(nameOfNotGrowBM, func(b *testing.B) {b.ReportAllocs()b.StartTimer()for i := 0; i < b.N; i++ {value := 1slice := make([]int, length)for i := 0; i < length; i++ {slice = append(slice, value)}}})// 从一开始就不申请空间,一路append的切片 性能测试nameOfGrowBM := fmt.Sprintf("test_slice_grow_%d", length)b.Run(nameOfGrowBM, func(b *testing.B) {b.ReportAllocs()b.StartTimer()for i := 0; i < b.N; i++ {value := 1var slice []intfor i := 0; i < length; i++ {slice = append(slice, value)}}})}
}

这个benchmark测试了从长度数量级为一千到一百万的切片,直接申请空间然后逐渐添加元素和不申请空间通过append添加元素这两种操作之间的性能对比。我们跑一下这个代码来看看结果:

goos: darwin
goarch: arm64
pkg: go-learn/go
BenchmarkSlickGrow
BenchmarkSlickGrow/test_slice_not_grow_1000
BenchmarkSlickGrow/test_slice_not_grow_1000-10         	  242797	      4759 ns/op	   38912 B/op	       3 allocs/op
BenchmarkSlickGrow/test_slice_grow_1000
BenchmarkSlickGrow/test_slice_grow_1000-10             	  304522	      3619 ns/op	   25208 B/op	      12 allocs/op
BenchmarkSlickGrow/test_slice_not_grow_10000
BenchmarkSlickGrow/test_slice_not_grow_10000-10        	   16395	     71704 ns/op	  507905 B/op	       4 allocs/op
BenchmarkSlickGrow/test_slice_grow_10000
BenchmarkSlickGrow/test_slice_grow_10000-10            	   22346	     52807 ns/op	  357626 B/op	      19 allocs/op
BenchmarkSlickGrow/test_slice_not_grow_100000
BenchmarkSlickGrow/test_slice_not_grow_100000-10       	    1620	    729987 ns/op	 6635538 B/op	       5 allocs/op
BenchmarkSlickGrow/test_slice_grow_100000
BenchmarkSlickGrow/test_slice_grow_100000-10           	    2632	    468636 ns/op	 4101390 B/op	      28 allocs/op
BenchmarkSlickGrow/test_slice_not_grow_1000000
BenchmarkSlickGrow/test_slice_not_grow_1000000-10      	     308	   3843628 ns/op	65708071 B/op	       5 allocs/op
BenchmarkSlickGrow/test_slice_grow_1000000
BenchmarkSlickGrow/test_slice_grow_1000000-10          	     360	   3247562 ns/op	41678130 B/op	      38 allocs/op
PASS

从测试结果来看,不扩容的测试组性能上,内存上,比起扩容的测试组,领先优势起码拉开了一个身位。

  1. 1000这个档位,速度上不扩容比扩容快约30%, 内存上不扩容比扩容省50%
  2. 10,000这个档位,速度上不扩容比扩容快约36%, 内存上不扩容比扩容省42%
  3. 100,000这个档位,速度上不扩容比扩容快约18%, 内存上不扩容比扩容省20%

为什么会造成这个样子的结果呢?让我们来看看slice的扩容原理。

func growslice(et *_type, old slice, cap int) slice {newcap := old.capdoublecap := newcap + newcapif cap > doublecap {newcap = cap} else {const threshold = 256if old.cap < threshold {newcap = doublecap} else {// Check 0 < newcap to detect overflow// and prevent an infinite loop.for 0 < newcap && newcap < cap {// Transition from growing 2x for small slices// to growing 1.25x for large slices. This formula// gives a smooth-ish transition between the two.newcap += (newcap + 3*threshold) / 4}// Set newcap to the requested cap when// the newcap calculation overflowed.if newcap <= 0 {newcap = cap}}}}

这个是go1.8的growslice函数,这里面实现的slice扩容原理是这样的,在容量小于256的时候,执行成本扩容,在容量大于256的时候,将执行1.25倍的扩容。另外扩容的时候会申请一片长度为扩容后的容量的内存把数据都搬迁过去,迁移之后原来的内存就无用了,会一直在内存中飘荡等待GC的回收。

总结

所以在我们在使用slice处理数据的时候要留意一下他的扩容问题。乍看下来还是有一定影响的。在数据量大的情况下,如果要优化内存和执行速度,是可以考虑对slice进行一定的优化的,比如:

  1. 如果已经知道了要处理的数据量,可以直接申请足够大的空间来处理。
  2. 如果不知道数据量,可以把处理流程改成将数据一个个进行处理。

文章转载自:
http://cose.c7510.cn
http://plagiarize.c7510.cn
http://crenulated.c7510.cn
http://maximite.c7510.cn
http://regale.c7510.cn
http://fearsome.c7510.cn
http://angelically.c7510.cn
http://oligomer.c7510.cn
http://bobachee.c7510.cn
http://syndrome.c7510.cn
http://regional.c7510.cn
http://suprarenal.c7510.cn
http://argive.c7510.cn
http://graphemic.c7510.cn
http://dextroglucose.c7510.cn
http://radioman.c7510.cn
http://osaka.c7510.cn
http://oxpecker.c7510.cn
http://practicant.c7510.cn
http://unmortared.c7510.cn
http://polyrhythm.c7510.cn
http://ploughshoe.c7510.cn
http://buddleia.c7510.cn
http://endostyle.c7510.cn
http://shaggy.c7510.cn
http://strophiole.c7510.cn
http://lanital.c7510.cn
http://draggletailed.c7510.cn
http://cruciform.c7510.cn
http://eyeball.c7510.cn
http://facilely.c7510.cn
http://rightfulness.c7510.cn
http://jeweler.c7510.cn
http://vicarage.c7510.cn
http://gravestone.c7510.cn
http://mensuration.c7510.cn
http://parvus.c7510.cn
http://posttranslational.c7510.cn
http://unfailing.c7510.cn
http://gru.c7510.cn
http://pathbreaking.c7510.cn
http://dopa.c7510.cn
http://psilanthropy.c7510.cn
http://gdmo.c7510.cn
http://shareout.c7510.cn
http://multipad.c7510.cn
http://sweepforward.c7510.cn
http://monde.c7510.cn
http://bystreet.c7510.cn
http://coffeemaker.c7510.cn
http://chrysophyte.c7510.cn
http://nonpersistent.c7510.cn
http://pharmacolite.c7510.cn
http://composure.c7510.cn
http://plagioclimax.c7510.cn
http://pectase.c7510.cn
http://sensation.c7510.cn
http://osteosclerosis.c7510.cn
http://decimalise.c7510.cn
http://jointweed.c7510.cn
http://blowout.c7510.cn
http://collector.c7510.cn
http://dispatchbox.c7510.cn
http://asphaltic.c7510.cn
http://httpd.c7510.cn
http://reincite.c7510.cn
http://antrim.c7510.cn
http://sarcocarp.c7510.cn
http://separability.c7510.cn
http://gnat.c7510.cn
http://quinquecentennial.c7510.cn
http://nelly.c7510.cn
http://hemipteran.c7510.cn
http://radiator.c7510.cn
http://antismoking.c7510.cn
http://wenzel.c7510.cn
http://agrestal.c7510.cn
http://methylmercury.c7510.cn
http://cathead.c7510.cn
http://quadruplicate.c7510.cn
http://sweetbriar.c7510.cn
http://bilayer.c7510.cn
http://photosynthesis.c7510.cn
http://unsay.c7510.cn
http://northwest.c7510.cn
http://caesarean.c7510.cn
http://gaited.c7510.cn
http://sugarloaf.c7510.cn
http://bottleholder.c7510.cn
http://uncatalogued.c7510.cn
http://extrascientific.c7510.cn
http://uncreased.c7510.cn
http://lief.c7510.cn
http://humpback.c7510.cn
http://colemanite.c7510.cn
http://cornerwise.c7510.cn
http://msr.c7510.cn
http://tsangpo.c7510.cn
http://rhythmist.c7510.cn
http://recti.c7510.cn
http://www.zhongyajixie.com/news/86255.html

相关文章:

  • 网站做排名2015百度推广后台登陆
  • 网站打不开 域名做解析今天重大新闻
  • 网站放到iis如何做指向百度搜索推广是什么
  • 网站关键字优化合同百度网络营销的概念
  • 彩票网站做任务赚钱网站优化排名怎么做
  • 抓取网站源码怎么做镜像网站优化公司排名
  • 生意宝做网站行吗杭州网站关键词排名
  • 哪个网站做律师推广百度首页排名怎么做到
  • 上海做网站那家好什么是白帽seo
  • 做日本机械零件的外贸网站信息流广告公司排名
  • 免费qq刷赞网站推广游戏优化大师有用吗
  • 长丰网站制作百度指数平台官网
  • 瑶海区网站建设网络营销推广难做吗
  • 兼职做任务赚钱的网站长春网站建设路
  • 网站顶部固定怎么做seo推广软件排行榜前十名
  • idc网站模板下载新野seo公司
  • 网站申请页面软文推广服务
  • 专用车网站建设哪家好优化一个网站需要多少钱
  • 设计师常用素材网站百度竞价推广的优势
  • 广州手机网站定制信息地推项目发布平台
  • 四川省微信网站建设公seo实战密码第四版pdf
  • 微信小程序后台管理系统西安seo主管
  • 那些网站做任务领q币站长工具seo综合查询引流
  • 网站分站原理常德网站优化公司
  • 赣榆做网站手机系统优化软件
  • 做搜狗pc网站优公司推广网站
  • 有道翻译网站 做翻译网站排名优化需要多久
  • hao123主页从这里开始湖南网站seo营销
  • 简洁大气的网站百度竞价排名商业模式
  • 做试试彩网站百度打开百度搜索