gpt4 book ai didi

浅谈golang 的高效编码细节

转载 作者:qq735679552 更新时间:2022-09-27 22:32:09 27 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章浅谈golang 的高效编码细节由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

xdm,我们都知道 golang 是天生的高并发,高效的编译型语言 。

可我们也都可知道,工具再好,用法不对,全都白费,我们来举 2 个常用路径来感受一下 。

struct 和 map 用谁呢?

计算量很小的时候,可能看不出使用 临时 struct 和 map 的耗时差距,但是数量起来了,差距就明显了,且会随着数量越大,差距越发明显 。

当我们遇到键和值都可以是固定的时候,我们选择 struct 比 选择 map 的方式 高效多了 。

  • 我们模拟循环计算 1 亿 次,看看使用各自的数据结构会耗时多少
  • 循环前计算一下当前时间
  • 循环后计算一下当前时间
  • 最后计算两个时间的差值,此处我们使用 毫秒为单位
?
1
2
3
4
5
6
7
8
9
10
11
12
13
func main() {
  t1 :=time.Now().UnixNano()/1e6
  for i := 0; i < 100000000; i++ {
   var test struct {
    Name  string
    hobby string
   }
   test.Name = "xiaomotong"
   test.hobby = "program"
  }
  t2 :=time.Now().UnixNano()/1e6
  fmt.Println("t2 - t1 == ", t2-t1)
}

程序运行查看效果:

# go run main.go t1 ==  1634377149185 t2 ==  1634377149221 t2 - t1 ==  36 。

使用 struct 的方式,耗时 36 ms ,大家感觉这个时间如何?

我们一起来看看使用 map 的方式吧 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
func main() {
  t1 :=time.Now().UnixNano()/1e6
  fmt.Println("t1 == ", t1)
 
  for i := 0; i < 100000000; i++ {
   var test = map[string]interface{}{}
   test["name"] = "xiaomotong"
   test["hobby"] = "program"
  }
  t2 :=time.Now().UnixNano()/1e6
  fmt.Println("t2 == ", t2)
  fmt.Println("t2 - t1 == ", t2-t1)
}

程序运行查看效果:

# go run main.go t1 ==  1634377365927 t2 ==  1634377373525 t2 - t1 ==  7598 。

使用 struct 的方式,耗时 7598 ms 。

使用 map 和 使用 struct 的方式,完成同样数据处理,耗时相差 212 倍 , 就这,我们平时编码的时候,对于上述的场景,你会选择哪种数据结构呢?

为什么上述差距会那么大,原因是 。

在我们可以确定字段的情况下,我们使用 临时的 Struct 在运行期间是不需要动态分配内容的, 。

可是 map 就不一样,map 还要去检查索引,这一点就非常耗时了 。

字符串如何拼接是好?

工作中编码 xdm 遇到字符串拼接的情况,都是如何实现的呢?我们的工具暂时提供如下几种:

  • 使用 + 的方式
  • 使用 fmt.Sprintf() 的方式
  • 使用 strings.Join 的方式
  • 使用 buffer 的方式

看到这里,也许我们各有各的答案,不过我们还是来实操一遍,看看他们在相同字符串拼接情况下,各自的处理耗时如何 。

用 + 的方式

我们来计算循环追加 50 万 次字符串,看看耗时多少 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
func main() {
 
  t1 := time.Now().UnixNano() / 1e6
  fmt.Println("t1 == ", t1)
 
  s := "xiao"
  for i := 0; i < 500000; i++ {
   s += "motong"
  }
 
  t2 := time.Now().UnixNano() / 1e6
  fmt.Println("t2 == ", t2)
  fmt.Println("t2 - t1 == ", t2-t1)
}

程序运行查看效果:

# go run main.go t1 ==  1634378595642 t2 ==  1634378743119 t2 - t1 ==  147477 。

看到这个数据 xdm 有没有惊呆了,居然这么慢,耗时 147477 ms 那可是妥妥的 2分27秒呀 。

Go语言 中使用+处理字符串是很消耗性能的,通过数据我们就可以看出来 。

使用 fmt.Sprintf() 的方式

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
func main() {
 
  t1 := time.Now().UnixNano() / 1e6
  fmt.Println("t1 == ", t1)
 
  s := "xiao"
  for i := 0; i < 500000; i++ {
   s = fmt.Sprintf("%s%s",s,"motong")
  }
 
  t2 := time.Now().UnixNano() / 1e6
  fmt.Println("t2 == ", t2)
  fmt.Println("t2 - t1 == ", t2-t1)
}

程序运行查看效果:

# go run main.go t1 ==  1634378977361 t2 ==  1634379240292 t2 - t1 ==  262931 。

看到这个数据,咱们也惊呆了,居然耗时 262931 ms,合计 4 分 22秒 ,xdm 是不是没有想到 使用 fmt.Sprintf 比 使用 + 还慢 。

使用 strings.Join 的方式

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
func main() {
 
  t1 := time.Now().UnixNano() / 1e6
  fmt.Println("t1 == ", t1)
 
  s := "xiao"
  for i := 0; i < 500000; i++ {
   s = strings.Join([]string{s,"motong"},"")
  }
 
  t2 := time.Now().UnixNano() / 1e6
  fmt.Println("t2 == ", t2)
  fmt.Println("t2 - t1 == ", t2-t1)
}

程序运行查看效果:

# go run main.go t1 ==  1634379455304 t2 ==  1634379598227 t2 - t1 ==  142923 。

耗时 142923 ms ,合计 2 分 22秒 ,和 使用 +的方式不相上下 。

使用 buffer 的方式

使用 buffer 的方式 应该说是最好的方式, 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
func main() {
 
  t1 := time.Now().UnixNano() / 1e6
  fmt.Println("t1 == ", t1)
 
  s := bytes.NewBufferString("xiao")
  for i := 0; i < 500000; i++ {
   s.WriteString("motong")
  }
 
  t2 := time.Now().UnixNano() / 1e6
  fmt.Println("t2 == ", t2)
  fmt.Println("t2 - t1 == ", t2-t1)
}

# go run main.go t1 == 1634378506021 t2 == 1634378506030 t2 - t1 == 9 。

通过上面的数据,我们看到,拼接同样 50 万次的数据 。

  • 第一种,使用 + 的方式 ,需要 147477 ms
  • 第二种,使用 fmt.Sprintf() 的方式,需要 262931 ms
  • 第三种,使用 strings.Join 的方式,需要 142923 ms
  • 第四种,使用 buffer 的方式 ,需要 9ms

使用 buffer 的方式 是 第一种的 16,386 倍 ,是第二种的 29,214 倍 ,是第三种的 15,880 倍 。

xdm ,如果是遇到上面的场景,你会选择使用哪一种方式呢 。

到此这篇关于浅谈golang 的高效编码细节的文章就介绍到这了,更多相关golang 高效编码内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。

原文链接:https://juejin.cn/post/7019608237326467079 。

最后此篇关于浅谈golang 的高效编码细节的文章就讲到这里了,如果你想了解更多关于浅谈golang 的高效编码细节的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com