首页 > 其他分享 >uber go code 规范(性能)

uber go code 规范(性能)

时间:2022-09-30 11:13:44浏览次数:58  
标签:uber code ++ fmt Now time go main

前言

从接触 Golang 到现在, 感觉到的很深的一点是, go 的代码无论是大佬还是菜鸟写出的代码, 都有着大体统一的 格式/流程, 这也是 Go 被开发者喜爱的一个原因, 但是还有一些, 比如变量的命名方式等, 可以称之为 风格 的东西, 却不尽相同, 我在开发中, 其实也希望有一个相对权威的指导意见, 后来就找到了 uber 团队出品的开发规范.
uber 是众多公司中, 比较早使用 go 语言的了, 其本身也开源了一些优质的模块, 有机会的话希望也能向大家展示一下, 而在 uber 内部开发中, 经过持续的迭代, 开源了自己的代码规范, 这里给大家解读一下
需要特别指出的是, 下面的内容并不是一定需要遵守, 这里你可以选择自己认为正确的可行的规范.
团队内使用统一的风格, 可以提高代码的可读性
本篇记录性能部分, 旨在特定情况下提高程序的性能

优先使用 strconv 而不是 fmt

将 int 转换成 string 时, 使用 strconv 的方法比 fmt 的速度更快
错误的

package main

import (
	"fmt"
	"strconv"
	"time"
)

func main() {
	start := time.Now()
	for i := 0; i < 10000; i++ {
		fmt.Sprintln(i)
	}
	fmt.Println(time.Now().Sub(start))
}

查看耗时

➜  test go run main.go
872.779µs

正确的

package main

import (
	"fmt"
	"strconv"
	"time"
)

func main() {
	start := time.Now()
	for i := 0; i < 10000; i++ {
		strconv.Itoa(i)
	}
	fmt.Println(time.Now().Sub(start))
}

查看耗时

➜  test go run main.go
233.211µs

避免字符串转换成字节

不要频繁的从固定字符串转换成字节, 而是只创建一次并将结果保存, 反复使用
错误的

package main

import (
	"fmt"
	"time"
)

func main() {
	start := time.Now()
	for i := 0; i < b.N; i++ {
		 w.Write([]byte("Hello world"))
	}
	fmt.Println(time.Now().Sub(start))
}

正确的

package main

import (
	"fmt"
	"time"
)

func main() {
	start := time.Now()
	data := []byte("Hello world")
	for i := 0; i < b.N; i++ {
	  w.Write(data)
	}
	fmt.Println(time.Now().Sub(start))
}

初始化 Map 和切片时预估长度

在初始化 map 和切片时, 就指定其长度, 防止 go 进行动态扩容

map

使用 make 进行初始化时提供容量信息

make(map[T]T, len)

这可能会减少动态扩容的次数, 因为 go 的 map 容量不是一定准确判断, 所以只是可能减少
错误的

m := make(map[string]os.FileInfo)

files, _ := ioutil.ReadDir("./files")
for _, f := range files {
    m[f.Name()] = f
}

正确的


files, _ := ioutil.ReadDir("./files")

m := make(map[string]os.FileInfo, len(files))  // 直接指定长度
for _, f := range files {
    m[f.Name()] = f
}

指定切片容量

在创建切片时, 尽可能的提供容量信息

make([]T, length, capacity)

go 对切片的处理, 当切片长度够用时, 一定不会出现分配操作, 节省时间
错误的

for n := 0; n < b.N; n++ {
  data := make([]int, 0)  // 长度为0
  for k := 0; k < size; k++{
    data = append(data, k)  // 长度不够时进行扩容
  }
}

正确的

for n := 0; n < b.N; n++ {
  data := make([]int, 0, size)  // 指定 size
  for k := 0; k < size; k++{
    data = append(data, k)  // 永远不会扩容
  }
}

标签:uber,code,++,fmt,Now,time,go,main
From: https://www.cnblogs.com/chnmig/p/16744230.html

相关文章

  • vscode 设置引用分层
    前言对于一个团队来讲,维持一样的代码风格非常重要.而现代的开发工具,都提供了很好的支持,这里简单记录一下VsCode的一些设置VsCode安装Go插件在VsCode中安......
  • mongo 初探触发器
    前言mongo作为出名的nosql数据库,随着版本的迭代,被越来越多的开发者所接受,DB-EnginesRanking-popularityrankingofdatabasemanagementsystems而我们今......
  • Golang map 的底层原理
    前言本文介绍golang中map的实现方式,希望对读者和我有所帮助结构map是go语言中的基础的数据结构,在寻找指定key时,复杂度是O(1),在某些场景能发挥很大的作用......
  • Golang 的锁
    前言go语言的锁,一说大家都知道,一个是互斥锁Mutex,一个是读写互斥锁RWMutex,用起来很简单,但是要想在技术上更进一步,还是需要了解其原理基础知识进程同步既然......
  • go 语言的 slice 注意点
    前言起因是在编写某个模块时,考虑到slice良好的伸缩性,便使用slice来存储大量的数据,业务是slice的数据会慢慢的弹出减少,理想状态下内存占用会越来越少,结果发现,......
  • 【Kubernetes】K8s笔记(四):从 Job 和 CronJob 看 Kubernetes 的设计理念
    0.前言:在线业务和离线业务Kubernetes的业务可以分为两大类:在线业务和离线业务。在线业务:像Nginx、MySQL这样长时间运行的业务,这些应用一旦运行起来,除非出错或者停......
  • Golang 常问知识点(简略)
    前言稍微记录一下问题点吧,文章会不断的优化更新有些比较大的知识点,比如锁原理啥的,会单独拎出来写一篇,这里只是大概Go语言的基础数据类型占用大小类型大小......
  • [CodeForce] Maximum Subsequence
    ProblemStatement 1.Nisupto35,sotryingallpossiblesubsequencesistooslow(2^35).WecanapplythemeetinthemiddletechniqueanddivideAinto......
  • vscode 指定 anaconda创建的python虚拟环境
    1点击左下角的设置。2点击commandpalette。3搜索框输入Python:SelectInterpreter。4选择虚拟环境。......
  • Educational Codeforces Round 136 C-D
    D.ResetKEdges显然对于每个k每个答案具有单调性我们考虑二分一个能保留的最大长度x然后我们自上至下肯定不好操作我们考虑自下而上对于每次到达了我们最大长度x......