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

企业建网站seo排名怎么优化软件

企业建网站,seo排名怎么优化软件,威县做网站哪儿好,彩票网站开发 合法g o l a n g golang golang的 s t r i n g string string类型是不可修改的,对于拼接字符串来说,本质上还是创建一个新的对象将数据放进去。主要有以下几种拼接方式 拼接方式介绍 1.使用 s t r i n g string string自带的运算符 ans ans s2. 使用…

g o l a n g golang golang s t r i n g string string类型是不可修改的,对于拼接字符串来说,本质上还是创建一个新的对象将数据放进去。主要有以下几种拼接方式

拼接方式介绍

1.使用 s t r i n g string string自带的运算符 + + +

ans = ans + s

2. 使用格式化输出 f m t . S p r i n t f fmt.Sprintf fmt.Sprintf

ans = fmt.Sprintf("%s%s", ans, s)

3. 使用 s t r i n g s strings strings j o i n join join函数

一般适用于将字符串数组转化为特定间隔符的字符串的情况

ans=strings.join(strs,",")

4. 使用 s t r i n g s . B u i l d e r strings.Builder strings.Builder

builder := strings.Builder{}
builder.WriteString(s)
return builder.String()

5. 使用 b y t e s . B u f f e r bytes.Buffer bytes.Buffer

buffer := new(bytes.Buffer)
buffer.WriteString(s)
return buffer.String()

6. 使用 [ ] b y t e []byte []byte,并且提前设置容量

ans := make([]byte, 0, len(s)*n)
ans = append(ans, s...)

性能对比

先写一个随机生成长度为 n n n的字符串的函数

func getRandomString(n int) string {var tmp = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"ans := make([]uint8, 0, n)for i := 0; i < n; i++ {ans = append(ans, tmp[rand.Intn(len(tmp))])}return string(ans)
}

接下来分别写出上述拼接方式的实现,假设每次都拼接n次字符串s后返回。

1.使用 s t r i n g string string自带的运算符 + + +

循环 n n n次,每次都令答案字符串 a n s + ans+ ans+源字符串 s s s

func plusOperatorJoin(n int, s string) string {var ans stringfor i := 0; i < n; i++ {ans = ans + s}return ans
}

2. 使用格式化输出 f m t . S p r i n t f fmt.Sprintf fmt.Sprintf

循环 n n n次,使用 f m t . S p r i n t f fmt.Sprintf fmt.Sprintf达到拼接的目的

func sprintfJoin(n int, s string) string {var ans stringfor i := 0; i < n; i++ {ans = fmt.Sprintf("%s%s", ans, s)}return ans
}

3. 使用 s t r i n g s strings strings j o i n join join函数

拼接同一个字符串的话不适合用 j o i n join join函数,所以跳过这种方式

4. 使用 s t r i n g s . B u i l d e r strings.Builder strings.Builder

初始化 s t r i n g s . B u i l d e r strings.Builder strings.Builder,循环 n n n次,每次调用 W r i t e S t r i n g WriteString WriteString方法

func stringBuilderJoin(n int, s string) string {builder := strings.Builder{}for i := 0; i < n; i++ {builder.WriteString(s)}return builder.String()
}

5. 使用 b y t e s . B u f f e r bytes.Buffer bytes.Buffer

初始化 b y t e s . B u f f e r bytes.Buffer bytes.Buffer,循环 n n n次,每次调用 W r i t e S t r i n g WriteString WriteString方法

func bytesBufferJoin(n int, s string) string {buffer := new(bytes.Buffer)for i := 0; i < n; i++ {buffer.WriteString(s)}return buffer.String()
}

6. 使用 [ ] b y t e []byte []byte,并且提前设置容量

定义 a n s ans ans b y t e byte byte数组,并提前设置容量为 l e n ( s ) ∗ n len(s)*n len(s)n

func bytesJoin(n int, s string) string {ans := make([]byte, 0, len(s)*n)for i := 0; i < n; i++ {ans = append(ans, s...)}return string(ans)
}

测试代码

先随机生成一个长度为10的字符串,然后拼接10000次。

package high_stringsimport "testing"func benchmark(b *testing.B, f func(int, string) string) {var str = getRandomString(10)for i := 0; i < b.N; i++ {f(10000, str)}
}func BenchmarkPlusOperatorJoin(b *testing.B) {benchmark(b, plusOperatorJoin)
}
func BenchmarkSprintfJoin(b *testing.B) {benchmark(b, sprintfJoin)
}
func BenchmarkStringBuilderJoin(b *testing.B) {benchmark(b, stringBuilderJoin)
}
func BenchmarkBytesBufferJoin(b *testing.B) {benchmark(b, bytesBufferJoin)
}
func BenchmarkBytesJoin(b *testing.B) {benchmark(b, bytesJoin)
}

测试结果:

在这里插入图片描述

使用 [ ] b y t e []byte []byte > s t r i n g s . B u i l d e r strings.Builder strings.Builder >= b y t e s . B u f f e r bytes.Buffer bytes.Buffer > f m t . S p r i n t f fmt.Sprintf fmt.Sprintf > + + +运算符

源码分析

1.使用 s t r i n g string string自带的运算符 + + +

代码在runtime\string.go


// concatstrings implements a Go string concatenation x+y+z+...
// The operands are passed in the slice a.
// If buf != nil, the compiler has determined that the result does not
// escape the calling function, so the string data can be stored in buf
// if small enough.
func concatstrings(buf *tmpBuf, a []string) string {idx := 0l := 0count := 0for i, x := range a {n := len(x)if n == 0 {continue}if l+n < l {throw("string concatenation too long")}l += ncount++idx = i}if count == 0 {return ""}// If there is just one string and either it is not on the stack// or our result does not escape the calling frame (buf != nil),// then we can return that string directly.if count == 1 && (buf != nil || !stringDataOnStack(a[idx])) {return a[idx]}s, b := rawstringtmp(buf, l)for _, x := range a {copy(b, x)b = b[len(x):]}return s
}
  • 首先计算拼接后的字符串长度
  • 如果只有一个字符串并且不在栈上就直接返回
  • 如果 b u f buf buf不为空并且 b u f buf buf可以放下这些字符串,就把拼接后的字符串放在 b u f buf buf里,否则在堆上重新申请一块内存
func rawstringtmp(buf *tmpBuf, l int) (s string, b []byte) {if buf != nil && l <= len(buf) {b = buf[:l]s = slicebytetostringtmp(&b[0], len(b))} else {s, b = rawstring(l)}return
}
// rawstring allocates storage for a new string. The returned
// string and byte slice both refer to the same storage.
// The storage is not zeroed. Callers should use
// b to set the string contents and then drop b.
func rawstring(size int) (s string, b []byte) {p := mallocgc(uintptr(size), nil, false)return unsafe.String((*byte)(p), size), unsafe.Slice((*byte)(p), size)
}
  • 然后遍历数组,将字符串 c o p y copy copy过去

2. 使用 s t r i n g s . B u i l d e r strings.Builder strings.Builder

介绍: s t r i n g s . B u i l d e r strings.Builder strings.Builder用于使用 W r i t e Write Write方法高效地生成字符串,它最大限度地减少了内存复制
拼接过程: b u i l d e r builder builder里有一个 b y t e byte byte类型的切片,每次调用 W r i t e S t r i n g WriteString WriteString的时候,是直接往该切片里追加字符串。因为切片底层的扩容机制是以倍数申请的,所以对比1而言,2的内存消耗要更少。
**结果返回:**在返回字符串的 S t r i n g String String方法里,是将 b u f buf buf数组转化为字符串直接返回的。
扩容机制: 想要缓冲区容量增加 n n n个字节,扩容后容量变为 2 ∗ l e n + n 2*len+n 2len+n

// A Builder is used to efficiently build a string using Write methods.
// It minimizes memory copying. The zero value is ready to use.
// Do not copy a non-zero Builder.
type Builder struct {addr *Builder // of receiver, to detect copies by valuebuf  []byte
}// String returns the accumulated string.
func (b *Builder) String() string {return unsafe.String(unsafe.SliceData(b.buf), len(b.buf))
}// grow copies the buffer to a new, larger buffer so that there are at least n
// bytes of capacity beyond len(b.buf).
func (b *Builder) grow(n int) {buf := make([]byte, len(b.buf), 2*cap(b.buf)+n)copy(buf, b.buf)b.buf = buf
}
// WriteString appends the contents of s to b's buffer.
// It returns the length of s and a nil error.
func (b *Builder) WriteString(s string) (int, error) {b.copyCheck()b.buf = append(b.buf, s...)return len(s), nil
}

3. 使用 b y t e s . B u f f e r bytes.Buffer bytes.Buffer

介绍 b y t e s . B u f f e r bytes.Buffer bytes.Buffer s t r i n g s . B u i l d e r strings.Builder strings.Builder的底层都是 b y t e byte byte数组,区别在于扩容机制和返回字符串的 S t r i n g String String方法。
结果返回: 因为 b y t e s . B u f f e r bytes.Buffer bytes.Buffer实际上是一个流式的字节缓冲区,可以向尾部写入数据,也可以读取头部的数据。所以在返回字符串的 S t r i n g String String方法里,只返回了缓冲区里未读的部分,所以需要重新申请内存来存放返回的结果。内存会比 s t r i n g s . B u i l d e r strings.Builder strings.Builder稍慢一些。
扩容机制: 想要缓冲区容量至少增加 n n n个字节, m m m是未读的长度, c c c是当前的容量。
优化点在于如果 n < = c / 2 − m n <= c/2-m n<=c/2m,也就是当前容量的一半都大于等于现有的内容(未读的字节数)加上所需要增加的字节数,就复用当前的数组,把未读的内容拷贝到头部去。

We can slide things down instead of allocating a new slice. We only need m+n <= c to slide, but we instead let capacity get twice as large so we don’t spend all our time copying.
我们可以向下滑动,而不是分配一个新的切片。我们只需要m+n<=c来滑动,但我们让容量增加了一倍,这样我们就不会把所有的时间都花在复制上。

否则的话也是 2 ∗ l e n + n 2*len+n 2len+n的扩张

// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
// The zero value for Buffer is an empty buffer ready to use.
type Buffer struct {buf      []byte // contents are the bytes buf[off : len(buf)]off      int    // read at &buf[off], write at &buf[len(buf)]lastRead readOp // last read operation, so that Unread* can work correctly.
}
// String returns the contents of the unread portion of the buffer
// as a string. If the Buffer is a nil pointer, it returns "<nil>".
//
// To build strings more efficiently, see the strings.Builder type.
func (b *Buffer) String() string {if b == nil {// Special case, useful in debugging.return "<nil>"}return string(b.buf[b.off:])
}
// WriteString appends the contents of s to the buffer, growing the buffer as
// needed. The return value n is the length of s; err is always nil. If the
// buffer becomes too large, WriteString will panic with ErrTooLarge.
func (b *Buffer) WriteString(s string) (n int, err error) {b.lastRead = opInvalidm, ok := b.tryGrowByReslice(len(s))if !ok {m = b.grow(len(s))}return copy(b.buf[m:], s), nil
}// grow grows the buffer to guarantee space for n more bytes.
// It returns the index where bytes should be written.
// If the buffer can't grow it will panic with ErrTooLarge.
func (b *Buffer) grow(n int) int {m := b.Len()// If buffer is empty, reset to recover space.if m == 0 && b.off != 0 {b.Reset()}// Try to grow by means of a reslice.if i, ok := b.tryGrowByReslice(n); ok {return i}if b.buf == nil && n <= smallBufferSize {b.buf = make([]byte, n, smallBufferSize)return 0}c := cap(b.buf)if n <= c/2-m {// We can slide things down instead of allocating a new// slice. We only need m+n <= c to slide, but// we instead let capacity get twice as large so we// don't spend all our time copying.copy(b.buf, b.buf[b.off:])} else if c > maxInt-c-n {panic(ErrTooLarge)} else {// Add b.off to account for b.buf[:b.off] being sliced off the front.b.buf = growSlice(b.buf[b.off:], b.off+n)}// Restore b.off and len(b.buf).b.off = 0b.buf = b.buf[:m+n]return m
}

字符串拼接性能及原理
GoLang bytes.Buffer基础使用方法详解


文章转载自:
http://dinncolaplacian.ssfq.cn
http://dinncocarbolic.ssfq.cn
http://dinncomaturation.ssfq.cn
http://dinncoporcellanic.ssfq.cn
http://dinncorhadamanthus.ssfq.cn
http://dinncobeachnik.ssfq.cn
http://dinncohenequin.ssfq.cn
http://dinncopaperboard.ssfq.cn
http://dinncosubcenter.ssfq.cn
http://dinncokogai.ssfq.cn
http://dinncothivel.ssfq.cn
http://dinncoenema.ssfq.cn
http://dinncohunan.ssfq.cn
http://dinncodublin.ssfq.cn
http://dinncoperikaryon.ssfq.cn
http://dinncofascinatedly.ssfq.cn
http://dinncorostrum.ssfq.cn
http://dinncooctopod.ssfq.cn
http://dinncodamage.ssfq.cn
http://dinncopercutaneous.ssfq.cn
http://dinncoimpercipience.ssfq.cn
http://dinncoastrionics.ssfq.cn
http://dinncocrowbar.ssfq.cn
http://dinncoqda.ssfq.cn
http://dinncostratocruiser.ssfq.cn
http://dinncoafghan.ssfq.cn
http://dinncokerygma.ssfq.cn
http://dinncojigger.ssfq.cn
http://dinncoetymologicon.ssfq.cn
http://dinncobepowder.ssfq.cn
http://dinncoepiphenomenon.ssfq.cn
http://dinncodamar.ssfq.cn
http://dinncocircumvolute.ssfq.cn
http://dinncotantalum.ssfq.cn
http://dinncoacrimoniously.ssfq.cn
http://dinncoloopworm.ssfq.cn
http://dinncocompensable.ssfq.cn
http://dinncosankhya.ssfq.cn
http://dinncovancouver.ssfq.cn
http://dinncochemoreceptivity.ssfq.cn
http://dinncosucculent.ssfq.cn
http://dinncodivulsion.ssfq.cn
http://dinncomit.ssfq.cn
http://dinncoaurist.ssfq.cn
http://dinncobillabong.ssfq.cn
http://dinncocental.ssfq.cn
http://dinncoteasy.ssfq.cn
http://dinncocomedic.ssfq.cn
http://dinncosubstrate.ssfq.cn
http://dinncosellanders.ssfq.cn
http://dinncochenopod.ssfq.cn
http://dinncotrapezohedron.ssfq.cn
http://dinncosearching.ssfq.cn
http://dinncocolored.ssfq.cn
http://dinncoprepose.ssfq.cn
http://dinncomadrid.ssfq.cn
http://dinncoossia.ssfq.cn
http://dinncobuhr.ssfq.cn
http://dinncofica.ssfq.cn
http://dinnconovocastrian.ssfq.cn
http://dinncoisomerization.ssfq.cn
http://dinncorelaxedly.ssfq.cn
http://dinncoarchimage.ssfq.cn
http://dinncoaccomplishable.ssfq.cn
http://dinncostokehold.ssfq.cn
http://dinncoviviparous.ssfq.cn
http://dinncomedoc.ssfq.cn
http://dinncodifficile.ssfq.cn
http://dinncoincreately.ssfq.cn
http://dinncominamata.ssfq.cn
http://dinncosemiannually.ssfq.cn
http://dinnconomad.ssfq.cn
http://dinnconominee.ssfq.cn
http://dinncosmallshot.ssfq.cn
http://dinncomistle.ssfq.cn
http://dinncomacroglobulin.ssfq.cn
http://dinncoenarch.ssfq.cn
http://dinncocrookery.ssfq.cn
http://dinncocccs.ssfq.cn
http://dinnconoegenetic.ssfq.cn
http://dinncocandidate.ssfq.cn
http://dinncoopaquely.ssfq.cn
http://dinncopostharvest.ssfq.cn
http://dinncohusbandman.ssfq.cn
http://dinncoinsanely.ssfq.cn
http://dinncolasso.ssfq.cn
http://dinncoexterior.ssfq.cn
http://dinncohiberarchy.ssfq.cn
http://dinncowildebeest.ssfq.cn
http://dinncoelectuary.ssfq.cn
http://dinncodownmost.ssfq.cn
http://dinncoundiscovered.ssfq.cn
http://dinncohandy.ssfq.cn
http://dinncoscantily.ssfq.cn
http://dinncoechinulate.ssfq.cn
http://dinncospieler.ssfq.cn
http://dinncoaccusation.ssfq.cn
http://dinncoeubacterium.ssfq.cn
http://dinncowithin.ssfq.cn
http://dinncorhombi.ssfq.cn
http://www.dinnco.com/news/88327.html

相关文章:

  • 黑龙江网站开发公司百度seo关键词优化
  • 做推送好用的网站快速优化官网
  • 中小企业公司简介范本西安网站优化推广方案
  • 政府网站建设先进个人典型材料代发推广百度首页包收录
  • 广告型网站建设软文范例大全300字
  • 做推广比较好的网站推广优化方案
  • 广西网站建设营销公司江西优化中心
  • 可以做业务推广的网站有哪些百度seo点击排名优化
  • 沧州公司做网站一个平台怎么推广
  • 贵州省 政府网站建设网络营销第三版课本
  • 男女做爰高清免费视频网站网络营销网站建设案例
  • wordpress 模板丢失windows优化大师软件介绍
  • b2b网站建站网站建设工作总结
  • 义乌商城网站开发班级优化大师功能介绍
  • ps做网站边框推广资源seo
  • 技术支持:洛阳网站建设广告推广系统
  • 网站优化员seo招聘百度搜索关键词排名人工优化
  • 网站操作可行性分析成都疫情最新消息
  • wordpress头部导航栏代码seoul是什么国家
  • 做微信首图的网站在线视频用什么网址
  • 网站怎么做伪静态iis7.0网页浏览器
  • 珠海门户网站制作费用青岛网站建设有限公司
  • wordpress去掉竖线灰色词网站seo
  • vk社交网站做婚介seo资讯推推蛙
  • wordpress 购买南京seo外包平台
  • 庐阳网站快速排名seo优化总结
  • 网站首页布局设计工具未来网络营销的发展趋势
  • 百度不做网站外链是什么吉林网络seo
  • 可以上传网站的免费空间双11销售数据
  • 网站模板 psd免费b站推广网站详情