Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
// run:
//
// go test -test.bench="." -test.cpuprofile=prof.out
// go tool pprof ./gist.test prof.out
package main
import (
"bytes"
"testing"
)
var alphabet string
var subject []byte
var queryMap map[byte]bool
var querySlice []byte
func init() {
alphabet = "acgtryswkmbdhvnACGTRYSWKMBDHVN -"
// map
queryMap = make(map[byte]bool, len(alphabet))
for i := 0; i < len(alphabet); i++ {
queryMap[alphabet[i]] = true
}
// fmt.Println("queryMap:", queryMap)
// slice
max := -1
for i := 0; i < len(alphabet); i++ {
j := int(alphabet[i])
if max < j {
max = j
}
}
querySlice = make([]byte, max+1)
for i := 0; i < len(alphabet); i++ {
querySlice[int(alphabet[i])] = alphabet[i]
}
// fmt.Println("querySlice: ", querySlice)
text := `
GCCTGTCTCAGACTCTTGGGGGCCTTGCAGCCTCCACCCCTACAGTGCTGCCATCTGGCT
TCTCAGCAGGGACCGAGTGATGCCCCTCTCCCCTCTACTACCCCCCACCCCTCTACTTCC
TGGTGTCACGTGGAAGGCAGCTGCCCGGGTTTGCCTGTGACTCCACACCCAGCATGTCTG
TCCCCTGCCCCAGGTCAGGGTGGGGCCTCGGCTTCCGCAGGAAGTGGTCTTGGTGCCAGC
CCTGCTGCCCTGGCTTTGAGCTGGGGCCCAGTGCCCTCTGGGTCCTGCTGGCTGCAGCTG
GCCCTCGGGGAACCCGCACACACAGCAGGAGGGGCCTGCCCAGGCCCAGTGCTGACTCTC
TCCTGCCATGCTCTCGGGCCCAGAGGTGCCATCCAGCCCCTGCCGTCTATCCACCCATCT
GTTCCTCGTCCCCCAGGCTGCAGGGCTCCCCACGCCACTGCTGTGGCCGCCTCACCTGCT
CCCCCTGTCTCTTTGGTCTTGCAGTCGGCTTCTCTATGGCCACAGCCTACTTTTAGAAGT
GCAGCTCTGTTAGGAGCCTTGAAGGTACCCGGTGCGCGGGACAGTGCGGCCCGCCGCCCC
TGCATGCCCAGGCCGCACCCCATTAGCATCCATGATTCCTGGTAGCATTTGGAGACTGTC
GCTCATGTGACGTGGATCATGACATGGCTCCGGGGGCCCTGGCCATCCCCAGCCATAGTG
GCATTTACGAGGCAGATCCAGGGTTCAGCTGGGTGGCCGCCTTCTCACTGGCCTCTCCTC
CCCTCccctccctcagtcctccctcccctccctcagtcctccctcccctccctcagtcct
ccctcccctccctcagtcctccctcccctccctcAGCCCCTTCCCTGGCGGGCAGCCCGC
TGGAGCCCCCACTGTGCCCCTCCTATCCCCCTCCTTCTCTCTCCTGCCCCCATCTCGGAC
CCTCAGGCTGTTGGTTCTGAGTTCGCCTCCCACTCCCTCC
`
subject = []byte{}
for i := 0; i < len(text); i++ {
switch text[i] {
case '\r', '\n', ' ':
default:
subject = append(subject, text[i])
}
}
subject = bytes.Repeat(subject, 10000)
// fmt.Println(len(subject))
}
// BenchmarkMap uses map
func BenchmarkCheckLetterWithMap(t *testing.B) {
var ok bool
for i, letter := range subject {
if _, ok = queryMap[letter]; !ok {
t.Errorf("invalid letter: %s in %d\n", []byte{letter}, i)
return
}
}
}
// BenchmarkMap uses switch
func BenchmarkCheckLetterWithSwitch(t *testing.B) {
for i, letter := range subject {
switch letter {
case 'a', 'A':
case 'c', 'C':
case 'g', 'G':
case 't', 'T':
case ' ':
case '-':
default:
t.Errorf("invalid letter: %s in %d\n", []byte{letter}, i)
return
}
}
}
func BenchmarkCheckLetterWithSwitchWithLargerAlphabetSize(t *testing.B) {
for i, letter := range subject {
switch letter {
case 'a', 'A':
case 'c', 'C':
case 'g', 'G':
case 't', 'T':
case 'r', 'R':
case 'y', 'Y':
case 's', 'S':
case 'w', 'W':
case 'k', 'K':
case 'm', 'M':
case 'b', 'B':
case 'd', 'D':
case 'h', 'H':
case 'v', 'V':
case 'n', 'N':
case ' ':
case '-':
default:
t.Errorf("invalid letter: %s in %d\n", []byte{letter}, i)
return
}
}
}
// BenchmarkSlice uses slice
func BenchmarkCheckLetterWithSlice(t *testing.B) {
var value byte
var j int
var sliceSize = len(querySlice)
for i, letter := range subject {
j = int(letter)
if j >= sliceSize {
t.Errorf("invalid letter: %s in %d\n", []byte{letter}, i)
return
}
value = querySlice[int(letter)]
if value == 0 {
t.Errorf("invalid letter: %s in %d\n", []byte{letter}, i)
return
}
}
}
BenchmarkCheckLetterWithMap-4 2000000000 0.18 ns/op
BenchmarkCheckLetterWithSwitch-4 1000000000 0.02 ns/op
BenchmarkCheckLetterWithSwitchWithLargerAlphabetSize-4 1000000000 0.03 ns/op
BenchmarkCheckLetterWithSlice-4 2000000000 0.01 ns/op
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment