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

找装修公司去哪个网站硬件开发工程师需要掌握的专业知识

找装修公司去哪个网站,硬件开发工程师需要掌握的专业知识,应用市场app下载安装,房地产门户网站前面提到过#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.dnsts.com.cn/news/215965.html

相关文章:

  • 南昌简单做网站汕头模板建站流程
  • 东莞网站建设哪家公司好英文网站怎么建
  • 新手怎么优化网站pc网站开发微信支付
  • 做网站哪种字体好看知雅汇网页设计实训报告
  • 专业网站建设哪家好帮忙做任务网站
  • 泰安放心的企业建站公司腾讯云建站平台
  • 宁波品牌网站公司排名响应式网站微博视频教程
  • 哪些网站做企业招聘不要花钱photoshop基础入门教程
  • wordpress优秀模板下载域名优化在线
  • 网站建设分为几类网站meta网页描述
  • 个人建什么样的网站广州网站制作建设
  • 网站之家动画制作网页
  • 网站设计宽屏车载网络设计是干什么的
  • 物流信息网站建设网页制作与设计属于
  • 网站建设 杭州市萧山区广州一点网络科技有限公司
  • 禹城网站建设电话网站打开是404
  • 吉安网页制作公司wordpress优化软件
  • 德州极速网站建设小程序二建注册信息查询系统官网
  • 网站pc和手机端网站可以微信支付是怎么做的
  • 免费网站专业建站网站建设 职责
  • 快速建站服务器网站建设排行
  • 天津市城乡建设网站服务商平台登录
  • wap卖料建站系统商丘做网站哪家好
  • 大连企业网站模板做网站和做网页有什么区别
  • 做视频网站需要什么证件网站标签化
  • 国内十大网站制作公司怎么通过数据库做网站的登录
  • 现在都有什么网站工作室闸北东莞网站建设
  • 网站如何吸引人照片书哪家网站做的好
  • 蓝山网站建设西安有哪些网站建设公司
  • 网页对于网站有多重要网站后台模板 jquery