Skip to content

Instantly share code, notes, and snippets.

@chris124567
Created June 28, 2021 16:26
Show Gist options
  • Save chris124567/afc7c198a2fc1b995bd816556022ed80 to your computer and use it in GitHub Desktop.
Save chris124567/afc7c198a2fc1b995bd816556022ed80 to your computer and use it in GitHub Desktop.
package main
import (
"crypto/sha256"
"fmt"
"hash"
"math/rand"
"os"
"runtime/pprof"
"strconv"
"sync"
"testing"
"unsafe"
)
var bufPool = sync.Pool{
New: func() interface{} {
// length of a sha256 hash
b := make([]byte, 256)
return &b
},
}
var hashPool = sync.Pool{
New: func() interface{} {
return sha256.New()
},
}
func foo(n int) string {
// get buffer from pool
bufptr := bufPool.Get().(*[]byte)
defer bufPool.Put(bufptr)
buf := *bufptr
// reset buf
buf = buf[:0]
// what you suggested:
// var ba [256]byte
// buf := ba[:0]
// get hash object from pool
h := hashPool.Get().(hash.Hash)
defer hashPool.Put(h)
h.Reset()
x := strconv.AppendInt(buf, int64(n), 10)
for i := 0; i < 100000; i++ {
h.Write(x)
}
// reset whatever strconv.AppendInt put in the buf
buf = buf[:0]
sum := h.Sum(buf)
// this may seem like it "should" allocate, but it does not
// 256 bytes fits in the stack. if you experiment with other values
// like 99999, you will find it will allocate because the stack space
// isnt that large
b := make([]byte, 0, 256)
for i := 0; i < int(sum[0]); i++ {
x := sum[(i*7+1)%len(sum)] ^ sum[(i*5+3)%len(sum)]
c := "abcdefghijklmnopqrstuvwxyz"[x%26]
b = append(b, c)
}
sum = sum[:0] // reset
sum = append(sum, b...)
return *(*string)(unsafe.Pointer(&sum))
}
func main() {
cpufile, err := os.Create("cpu.pprof")
if err != nil {
panic(err)
}
err = pprof.StartCPUProfile(cpufile)
if err != nil {
panic(err)
}
defer cpufile.Close()
defer pprof.StopCPUProfile()
// ensure function output is accurate
if foo(12345) == "aajmtxaattdzsxnukawxwhmfotnm" {
fmt.Println("Test PASS")
} else {
fmt.Println("Test FAIL")
}
fmt.Println("Allocs:", int(testing.AllocsPerRun(100, func() {
foo(rand.Int())
})))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment