1:在go语言中,先来看创建slice的性能分析,我们知道slice有append这个功能
t := time.Now() m := []string{} for i := 0; i < 1000000; i++ { m = append(m, strconv.Itoa(i)) } fmt.Println(time.Now().Sub(t))
可以看到添加了1000000项,花费时间368.0211ms。
我们也可以自己先定义一个具有固定长度的silice:
t := time.Now() m:=make([]string,1000000) for i := 0; i < 1000000; i++ { m[i]=strconv.Itoa(i) } fmt.Println(time.Now().Sub(t))
花费时间 52.003ms,感觉不错,性能提高了6-7倍。
Append是把原有的slice添加后,再赋予一个新的slice,就是不停的创建slice,而且属于接口类型,所以花费时间很多。
2:把slice连接成字符串。
第一种方法直接用strings.Join看下性能。
t := time.Now() s:=strings.Join(m,"") fmt.Println(time.Now().Sub(t)) fmt.Println(len(s))
花费12.0007ms。还是比较快的。
第二种方法,直接遍历。
s:="" t := time.Now() for i := 0; i < 1000000; i++ { s=s+m[i] } fmt.Println(time.Now().Sub(t)) fmt.Println(len(s))
很不幸的是,花了接近170秒,可以看到性能相差了1200倍。切记字符串很大的时候,别用S=S+a[i]这种方式,因为不停的创建内存空间来添加,不仅程序很卡,极大消耗了资源,而且还速度极慢。
____________________________________________________________
python中:
import time #第一种方式,append a=[] t=time.time() for i in range(1000000): a.append(str(i)) print(time.time()-t) 花费时间:0.34202003479003906秒 #第二种方式,列表推导 t=time.time() a=[str(i) for i in range(1000000)] print(time.time()-t) 花费时间:0.25701379776000977秒 第三种方式,先申请空间,再赋值 花费时间 0.3130180835723877秒 t=time.time() a = [1] * 1000000 for i in range(1000000): a[i]=str(i) print(time.time()-t)
可以看到,总的说来python中还是算平稳。
再看字符串连接方式1
t=time.time() s="".join(a) print(time.time()-t)
10W项花费时间 0.015001058578491211秒=15毫秒,和GO语言差不多。
再看字符串连接方式2
t=time.time() s="" for item in a: s=s+item print(time.time()-t) print(len(s))
花费时间1.6480939388275146秒,同样的方式比GO语言快了100倍,但是速度也很慢,所以也不建议使用这个东西。其实可以猜测,有些人使用编译型的语言写出来的程序的执行速度可能比一些脚本语言还慢。这个是靠程序员平时积累的经验了。
结论,遍历list连接字符串时候,切莫使用s=s+m[i]的这样的方式,尤其在list、slice元素够多的时候,不论在什么语言内,这个原则有效。
有疑问加站长微信联系(非本文作者)