Golang笔记

提高go运行性能小技巧

有几个tips 对提高go 性能有帮助,分享一下

Reflection 是昂贵的

Reflection来获取变量类型很方便,但会有性能消耗

代码行数的增加并不一定减少性能

比如下面功能的函数:

func add(items []string, item string) []string{
   return append(items,item)
}

代码很简洁、易懂,但性能不好,较好的方式:

func add(items []string, item string) []string{
   n := len(items)
   output := make([]string, n+1)
   for index, val := range items {
      output[index] = val
   }
   output[n] = item
   return output
}

基准测试代码:

package loc

import (
	"os"
	"testing"
)

const maxElements = 1000

var elements = make([]int, maxElements)

func TestMain(m *testing.M) {
	for i := 0; i < maxElements; i++ {
		elements[i] = i
	}
	os.Exit(m.Run())
}

func Add(items []int, item int) []int {
	return append(items, item)
}

func Add2(items []int, item int) []int {
	n := len(items)
	output := make([]int, n+1)
	output[n] = item
	copy(items[0:n], output)
	return output
}

func BenchmarkAdd(b *testing.B) {
	b.ReportAllocs()
	var result []int
	for i := 0; i < b.N; i++ {
		b.StartTimer()
		result = Add(elements, 10)
	}
	if len(result) != maxElements+1 {
		b.Fatalf("Invalid number of elements, expected %d but retrieved %d", maxElements+1, len(result))
	}
}

func BenchmarkAdd2(b *testing.B) {
	b.ReportAllocs()
	var result []int
	for i := 0; i < b.N; i++ {
		b.StartTimer()
		result = Add2(elements, 10)
	}
	if len(result) != maxElements+1 {
		b.Fatalf("Invalid number of elements, expected %d but retrieved %d", maxElements+1, len(result))
	}
}

// go test -bench=. -benchmem -memprofile memprofile.out -cpuprofile profile.out

当往1000个元素的数组添加一个元素时,第二种的性能是第一种的两倍。

使用内联函数

Testing

对象、变量尽可能长时间保留在内存中

Benchmark tests (基准测试)

本文网址: https://golangnote.com/topic/248.html (转载注明出处)
关于GolangNote:记录在工作中使用golang 遇到、面临的相关问题及解决方法。如果你在这里获得一些知识或信息,解决你的编程问题,请考虑捐赠给不幸的人或者你喜欢的慈善机构,除捐赠外,种植树木、志愿服务或减少排碳的行为也很有益处。如果你有任何问题可以在下面 留言
Comments
  • smallwhite
    Tue, 27 Aug 2019

    个人认为这种情况预先加cap会比较靠谱。

    
    import (
    	"os"
    	"testing"
    )
    
    const maxElements = 1000
    const cap = 2000
    
    var elements = make([]int, maxElements, cap)
    
    func TestMain(m *testing.M) {
    	for i := 0; i < maxElements; i++ {
    		elements[i] = i
    	}
    	os.Exit(m.Run())
    }
    
    func Add(items []int, item int) []int {
    	return append(items, item)
    }
    
    func Add2(items []int, item int) []int {
    	n := len(items)
    	output := make([]int, n+1)
    	output[n] = item
    	copy(items[0:n], output)
    	return output
    }
    
    func BenchmarkAdd(b *testing.B) {
    	b.ReportAllocs()
    	var result []int
    	for i := 0; i < b.N; i++ {
    		b.StartTimer()
    		result = Add(elements, 10)
    	}
    	if len(result) != maxElements+1 {
    		b.Fatalf("Invalid number of elements, expected %d but retrieved %d", maxElements+1, len(result))
    	}
    }
    
    func BenchmarkAdd2(b *testing.B) {
    	b.ReportAllocs()
    	var result []int
    	for i := 0; i < b.N; i++ {
    		b.StartTimer()
    		result = Add2(elements, 10)
    	}
    	if len(result) != maxElements+1 {
    		b.Fatalf("Invalid number of elements, expected %d but retrieved %d", maxElements+1, len(result))
    	}
    }
    
    
Leave a Comment
Captcha image
Relative Articles