我目前正在研究Go中的一些性能敏感代码.有一次,我有一个特别严密的内环,连续做三件事:
获取数据的几个指针.如果发生罕见错误,可能会有一个或多个指针nil
.
检查是否发生了此错误,如果有错误则记录错误.
处理存储在指针中的数据.
下面显示的是一个具有相同结构的玩具程序(虽然指针实际上永远不会是零).
package main
import (
"math/rand"
"fmt"
)
const BigScaryNumber = 1<<25
func DoWork() {
sum := 0
for i := 0; i < BigScaryNumber; i++ {
// Generate pointers.
n1, n2 := rand.Intn(20), rand.Intn(20)
ptr1, ptr2 := &n1, &n2
// Check if pointers are nil.
if ptr1 == nil || ptr2 == nil {
fmt.Printf("Pointers %v %v contain a nil.\n", ptr1, ptr2)
break
}
// Do work with pointer contents.
sum += *ptr1 …
Run Code Online (Sandbox Code Playgroud) performance memory-management variadic-functions go escape-analysis
我最近在大型数据集上运行了一些用Go编写的数字代码,并且遇到了内存管理问题.在尝试分析问题时,我用三种不同的方式测量了程序的内存使用情况:使用Go的runtime/pprof
包,使用unix time
实用程序,以及手动累加我分配的数据大小.这三种方法并没有给我一致的结果.
下面是我正在分析的代码的简化版本.它分配了几个切片,将值放在每个索引处,并将每个切片放在父切片中:
package main
import (
"fmt"
"os"
"runtime/pprof"
"unsafe"
"flag"
)
var mprof = flag.String("mprof", "", "write memory profile to this file")
func main() {
flag.Parse()
N := 1<<15
psSlice := make([][]int64, N)
_ = psSlice
size := 0
for i := 0; i < N; i++ {
ps := make([]int64, 1<<10)
for i := range ps { ps[i] = int64(i) }
psSlice[i] = ps
size += int(unsafe.Sizeof(ps[0])) * len(ps)
}
if *mprof != "" …
Run Code Online (Sandbox Code Playgroud) 我试图在Go中压缩字节切片compress/gzip
.每当我在笔记本电脑上压缩长度超过2 ^ 15的切片时,索引为2 ^ 15或更大的每个字节在解压缩后都会设置为0.当我在我的研究集群上运行相同的代码时,它也会中断.
打电话go version
给我的笔记本打印:
$ go version
go version go1.5 darwin/amd64
Run Code Online (Sandbox Code Playgroud)
调用go version
群集打印:
$ go version
go version go1.3.3 linux/amd64
Run Code Online (Sandbox Code Playgroud)
下面是我写的一个演示测试文件.它生成不同长度的随机切片,压缩它们,然后解压缩它们.它检查没有调用返回错误,并检查压缩和解压缩的切片是否相同:
package compress
import (
"bytes"
"compress/gzip"
"math/rand"
"testing"
)
func byteSliceEq(xs, ys []byte) bool {
if len(xs) != len(ys) { return false }
for i := range xs {
if xs[i] != ys[i] { return false }
}
return true
}
func TestGzip(t *testing.T) {
tests := []struct {
n …
Run Code Online (Sandbox Code Playgroud)