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

thinkphp网站建设网站建设维护问题

thinkphp网站建设,网站建设维护问题,优秀网页设计案例分析图文,电商的运营模式有几种前面提到过#xff0c;Go原生支持通过/操作符来连接多个字符串以构造一个更长的字符串#xff0c;并且通过/操作符的字符串连接构造是最自然、开发体验最好的一种。 但Go还提供了其他一些构造字符串的方法#xff0c;比如#xff1a; ● 使用fmt.Sprintf#xff1b; ● 使…前面提到过Go原生支持通过/操作符来连接多个字符串以构造一个更长的字符串并且通过/操作符的字符串连接构造是最自然、开发体验最好的一种。 但Go还提供了其他一些构造字符串的方法比如 ● 使用fmt.Sprintf ● 使用strings.Join ● 使用strings.Builder ● 使用bytes.Buffer。 在这些方法中哪种方法最为高效呢我们使用基准测试的数据作为参考 var sl []string []string{ Rob Pike , Robert Griesemer , Ken Thompson , } func concatStringByOperator(sl []string) string { var s string for _, v : range sl { s v } return s } func concatStringBySprintf(sl []string) string { var s string for _, v : range sl { s fmt.Sprintf(%s%s, s, v) } return s } func concatStringByJoin(sl []string) string { return strings.Join(sl, ) } func concatStringByStringsBuilder(sl []string) string { var b strings.Builder for _, v : range sl { b.WriteString(v) } return b.String() } func concatStringByStringsBuilderWithInitSize(sl []string) string { var b strings.Builder b.Grow(64)for _, v : range sl { b.WriteString(v) } return b.String() } func concatStringByBytesBuffer(sl []string) string { var b bytes.Buffer for _, v : range sl { b.WriteString(v) } return b.String() } func concatStringByBytesBufferWithInitSize(sl []string) string { buf : make([]byte, 0, 64) b : bytes.NewBuffer(buf) for _, v : range sl { b.WriteString(v) } return b.String() } func BenchmarkConcatStringByOperator(b *testing.B) { for n : 0; n b.N; n { concatStringByOperator(sl) } } func BenchmarkConcatStringBySprintf(b *testing.B) { for n : 0; n b.N; n { concatStringBySprintf(sl) } } func BenchmarkConcatStringByJoin(b *testing.B) { for n : 0; n b.N; n { concatStringByJoin(sl) } } func BenchmarkConcatStringByStringsBuilder(b *testing.B) { for n : 0; n b.N; n { concatStringByStringsBuilder(sl) } } func BenchmarkConcatStringByStringsBuilderWithInitSize(b *testing.B) { for n : 0; n b.N; n { concatStringByStringsBuilderWithInitSize(sl) } } func BenchmarkConcatStringByBytesBuffer(b *testing.B) { for n : 0; n b.N; n { concatStringByBytesBuffer(sl) } } func BenchmarkConcatStringByBytesBufferWithInitSize(b *testing.B) { for n : 0; n b.N; n { concatStringByBytesBufferWithInitSize(sl) } } 运行该基准测试 $go test -bench. -benchmem ./string_concat_benchmark_test.go goos: darwin goarch: amd64 BenchmarkConcatStringByOperator-8 11744653 89.1 ns/op 80 B/op 2 allocs/op BenchmarkConcatStringBySprintf-8 2792876 420 ns/op 176 B/op 8 allocs/op BenchmarkConcatStringByJoin-8 22923051 49.1 ns/op 48 B/op 1 allocs/op BenchmarkConcatStringByStringsBuilder-8 11347185 96.6 ns/op 112 B/op 3 allocs/op BenchmarkConcatStringByStringsBuilderWithInitSize-8 26315769 42.3 ns/op 64 B/op 1 allocs/op BenchmarkConcatStringByBytesBuffer-8 14265033 82.6 ns/op 112 B/op 2 allocs/op BenchmarkConcatStringByBytesBufferWithInitSize-8 24777525 48.1 ns/op 48 B/op 1 allocs/op PASS ok command-line-arguments 8.816s从基准测试的输出结果的第三列即每操作耗时的数值来看 ● 做了预初始化的strings.Builder连接构建字符串效率最高 ● 带有预初始化的bytes.Buffer和strings.Join这两种方法效率十分接近分列二三位 ● 未做预初始化的strings.Builder、bytes.Buffer和操作符连接在第三档次 ● fmt.Sprintf性能最差排在末尾。 由此可以得出一些结论 ● 在能预估出最终字符串长度的情况下使用预初始化的strings.Builder连接构建字符串效率最高 ● strings.Join连接构建字符串的平均性能最稳定如果输入的多个字符串是以[]string承载的那么strings.Join也是不错的选择 ● 使用操作符连接的方式最直观、最自然在编译器知晓欲连接的字符串个数的情况下使用此种方式可以得到编译器的优化处理 ● fmt.Sprintf虽然效率不高但也不是一无是处如果是由多种不同类型变量来构建特定格式的字符串那么这种方式还是最适合的。 转换 在前面的例子中我们看到了string到[]rune以及string到[]byte的转换这两个转 换也是可逆的也就是说string和[]rune、[]byte可以双向转换。下面就是从[]rune或 []byte反向转换为string的例子 func main() {rs : []rune{0x4E2D,0x56FD,0x6B22,0x8FCE,0x60A8,}s : string(rs)fmt.Println(s)sl : []byte{0xE4, 0xB8, 0xAD,0xE5, 0x9B, 0xBD,0xE6, 0xAC, 0xA2,0xE8, 0xBF, 0x8E,0xE6, 0x82, 0xA8,}s string(sl)fmt.Println(s) }$go run string_slice_to_string.go 中国欢迎您 中国欢迎您无论是string转slice还是slice转string转换都是要付出代价的这些代价的根源 在于string是不可变的运行时要为转换后的类型分配新内存。我们以byte slice与 string相互转换为例看看转换过程的内存分配情况 func byteSliceToString() { sl : []byte{ 0xE4, 0xB8, 0xAD, 0xE5, 0x9B, 0xBD, 0xE6, 0xAC, 0xA2, 0xE8, 0xBF, 0x8E, 0xE6, 0x82, 0xA8, 0xEF, 0xBC, 0x8C, 0xE5, 0x8C, 0x97, 0xE4, 0xBA, 0xAC, 0xE6, 0xAC, 0xA2, 0xE8, 0xBF, 0x8E,0xE6, 0x82, 0xA8, } _ string(sl) } func stringToByteSlice() { s : 中国欢迎您北京欢迎您 _ []byte(s) } func main() { fmt.Println(testing.AllocsPerRun(1, byteSliceToString)) fmt.Println(testing.AllocsPerRun(1, stringToByteSlice)) }运行这个例子 $go run string_mallocs_in_convert.go 1 1我们看到针对“中国欢迎您北京欢迎您”这个长度的字符串在string与byte slice互转的过程中都要有一次内存分配操作。 在Go运行时层面字符串与rune slice、byte slice相互转换对应的函数如下 slicebytetostring: []byte - string slicerunetostring: []rune - string stringtoslicebyte: string - []byte stringtoslicerune: string - []rune以byte slice为例看看slicebytetostring和stringtoslicebyte的实现 const tmpStringBufSize 32 type tmpBuf [tmpStringBufSize]byte func stringtoslicebyte(buf *tmpBuf, s string) []byte { var b []byte if buf ! nil len(s) len(buf) { *buf tmpBuf{} b buf[:len(s)] } else { b rawbyteslice(len(s)) } copy(b, s) return b }func slicebytetostring(buf *tmpBuf, b []byte) (str string) {l : len(b)if l 0 {return }// 此处省略一些代码if l 1 {stringStructOf(str).str unsafe.Pointer(staticbytes[b[0]])stringStructOf(str).len 1return}var p unsafe.Pointerif buf ! nil len(b) len(buf) {p unsafe.Pointer(buf)} else {p mallocgc(uintptr(len(b)), nil, false)}stringStructOf(str).str pstringStructOf(str).len len(b)memmove(p, (*(*slice)(unsafe.Pointer(b))).array, uintptr(len(b)))return }想要更高效地进行转换唯一的方法就是减少甚至避免额外的内存分配操作。我们看 到运行时实现转换的函数中已经加入了一些避免每种情况都要分配新内存操作的优化如 tmpBuf的复用。 slice类型是不可比较的而string类型是可比较的因此在日常Go编码中我们会经 常遇到将slice临时转换为string的情况。Go编译器为这样的场景提供了优化。在运行时中 有一个名为slicebytetostringtmp的函数就是协助实现这一优化的 func slicebytetostringtmp(b []byte) string {if raceenabled len(b) 0 {racereadrangepc(unsafe.Pointer(b[0]),uintptr(len(b)),getcallerpc(),funcPC(slicebytetostringtmp))}if msanenabled len(b) 0 {msanread(unsafe.Pointer(b[0]), uintptr(len(b)))}return *(*string)(unsafe.Pointer(b)) }该函数的“秘诀”就在于不为string新开辟一块内存而是直接使用slice的底层存 储。当然使用这个函数的前提是在原slice被修改后这个string不能再被使用了。因此 这样的优化是针对以下几个特定场景的。 1string(b)用在map类型的key中 b : []byte{k, e, y} m : make(map[string]string) m[string(b)] value m[[3]string{string(b), key1, key2}] value1 2string(b)用在字符串连接语句中 b : []byte{t, o, n, y} s : hello string(b) ! 3string(b)用在字符串比较中 s : tom b : []byte{t, o, n, y} if s string(b) { ... }Go编译器对用在for-range循环中的string到[]byte的转换也有优化处理它不会为 []byte进行额外的内存分配而是直接使用string的底层数据。 看下面的例子 func convert() { s : 中国欢迎您北京欢迎您 sl : []byte(s) for _, v : range sl { _ v } } func convertWithOptimize() { s : 中国欢迎您北京欢迎您 for _, v : range []byte(s) { _ v } } func main() { fmt.Println(testing.AllocsPerRun(1, convert)) fmt.Println(testing.AllocsPerRun(1, convertWithOptimize)) }运行这个例子程序 $go run string_for_range_covert_optimize.go 1 0从结果我们看到convertWithOptimize函数将string到[]byte的转换放在for-range 循环中Go编译器对其进行了优化节省了一次内存分配操作。
http://www.w-s-a.com/news/348081/

相关文章:

  • 企业网站有哪些举几个例子wordpress ie兼容插件
  • 高端的深圳网站页面设计福清市建设局官方网站
  • 安装网站到服务器合肥建设干部学校网站
  • 影视网站如何做销售案例网站
  • 建设网站对比方案龙岗网站开发公司
  • 网站开发标准网站建设公司兴田德润可信赖
  • 如何建设一个公众号电影网站自动seo优化
  • 个人网站能备案吗酱香拿铁采取了哪些网络营销方式
  • 网站建设及推广好做吗自己做的网站加入购物车价格
  • 涡阳在北京做网站的名人注册一个免费的网站
  • 三门峡建设环境局网站公司注册网上核名通道
  • 叶县建设局网站要看网海外域名是多少
  • 网站运行环境配置Wordpress支付时效
  • logo设计网站知乎港北网站建设
  • 北京市保障性住房建设投资中心官方网站有限责任公司的特点
  • 做网站卖互联网营销怎么做
  • 晋州市建设局网站建站网站系统
  • 专业网站优化方案广东微信网站制作报价表
  • 北京网站建设公司分形科技简述营销网站建设策略
  • 汉中网站建设有限公司vue网站开发
  • 网站备案背景幕布阳江东莞网站建设
  • 北京网站建设要多少钱html网站标签
  • 做兼职做网站的是什么公司网站怎么修改
  • 舆情监控都有哪些内容西安seo网站公司
  • 网站有域名没备案天津网络营销
  • 哈巴狗模式网站开发电子商务平台建设与运营技术
  • 摄影网站源码wordpress内涵段子
  • 实验一 电子商务网站建设与维护图片做网站
  • 网站策划书模板大全中国建设部官方网站资格证查询
  • vps绑定多个网站创意咨询策划公司