mirror of
https://github.com/golang/go
synced 2024-11-12 10:30:23 -07:00
166dab6993
As discussed on golang-dev, reduce the size of the fasta dataset to make it possible to run the go1 benchmarks on small ARM systems. Also, remove the 25m suffix from fasta data and Revcomp. linux/arm: pandaboard OMAP4 BenchmarkBinaryTree17 1 70892426000 ns/op BenchmarkFannkuch11 1 35712066000 ns/op BenchmarkGobDecode 10 137146000 ns/op 5.60 MB/s BenchmarkGobEncode 50 64953000 ns/op 11.82 MB/s BenchmarkGzip 1 5675690000 ns/op 3.42 MB/s BenchmarkGunzip 1 1207001000 ns/op 16.08 MB/s BenchmarkJSONEncode 5 860424800 ns/op 2.26 MB/s BenchmarkJSONDecode 1 3321839000 ns/op 0.58 MB/s BenchmarkMandelbrot200 50 45893560 ns/op BenchmarkRevcomp 10 135220300 ns/op 18.80 MB/s BenchmarkTemplate 1 6385681000 ns/op 0.30 MB/s R=rsc, minux.ma, dsymonds CC=golang-dev https://golang.org/cl/6278048
180 lines
3.6 KiB
Go
180 lines
3.6 KiB
Go
// Copyright 2011 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package go1
|
|
|
|
import "runtime"
|
|
|
|
// Not a benchmark; input for revcomp.
|
|
|
|
var fastabytes = makefasta()
|
|
|
|
func makefasta() []byte {
|
|
var n int = 25e6
|
|
if runtime.GOARCH == "arm" {
|
|
// TODO(dfc) remove this limitation after precise gc.
|
|
// A value of 25e6 consumes 465mb of heap on 32bit
|
|
// platforms, which is too much for most ARM systems.
|
|
// A value of 25e5 produces a memory layout that
|
|
// confuses the gc on 32bit platforms. So 25e4 it is.
|
|
n = 25e4
|
|
}
|
|
return fasta(n)
|
|
}
|
|
|
|
func fasta(n int) []byte {
|
|
out := make(fastaBuffer, 0, 11*n)
|
|
|
|
iub := []fastaAcid{
|
|
{prob: 0.27, sym: 'a'},
|
|
{prob: 0.12, sym: 'c'},
|
|
{prob: 0.12, sym: 'g'},
|
|
{prob: 0.27, sym: 't'},
|
|
{prob: 0.02, sym: 'B'},
|
|
{prob: 0.02, sym: 'D'},
|
|
{prob: 0.02, sym: 'H'},
|
|
{prob: 0.02, sym: 'K'},
|
|
{prob: 0.02, sym: 'M'},
|
|
{prob: 0.02, sym: 'N'},
|
|
{prob: 0.02, sym: 'R'},
|
|
{prob: 0.02, sym: 'S'},
|
|
{prob: 0.02, sym: 'V'},
|
|
{prob: 0.02, sym: 'W'},
|
|
{prob: 0.02, sym: 'Y'},
|
|
}
|
|
|
|
homosapiens := []fastaAcid{
|
|
{prob: 0.3029549426680, sym: 'a'},
|
|
{prob: 0.1979883004921, sym: 'c'},
|
|
{prob: 0.1975473066391, sym: 'g'},
|
|
{prob: 0.3015094502008, sym: 't'},
|
|
}
|
|
|
|
alu := []byte(
|
|
"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" +
|
|
"GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" +
|
|
"CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" +
|
|
"ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" +
|
|
"GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" +
|
|
"AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" +
|
|
"AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA")
|
|
|
|
out.WriteString(">ONE Homo sapiens alu\n")
|
|
fastaRepeat(&out, alu, 2*n)
|
|
out.WriteString(">TWO IUB ambiguity codes\n")
|
|
fastaRandom(&out, iub, 3*n)
|
|
out.WriteString(">THREE Homo sapiens frequency\n")
|
|
fastaRandom(&out, homosapiens, 5*n)
|
|
return out
|
|
}
|
|
|
|
type fastaBuffer []byte
|
|
|
|
func (b *fastaBuffer) Flush() {
|
|
panic("flush")
|
|
}
|
|
|
|
func (b *fastaBuffer) WriteString(s string) {
|
|
p := b.NextWrite(len(s))
|
|
copy(p, s)
|
|
}
|
|
|
|
func (b *fastaBuffer) NextWrite(n int) []byte {
|
|
p := *b
|
|
if len(p)+n > cap(p) {
|
|
b.Flush()
|
|
p = *b
|
|
}
|
|
out := p[len(p) : len(p)+n]
|
|
*b = p[:len(p)+n]
|
|
return out
|
|
}
|
|
|
|
const fastaLine = 60
|
|
|
|
func fastaRepeat(out *fastaBuffer, alu []byte, n int) {
|
|
buf := append(alu, alu...)
|
|
off := 0
|
|
for n > 0 {
|
|
m := n
|
|
if m > fastaLine {
|
|
m = fastaLine
|
|
}
|
|
buf1 := out.NextWrite(m + 1)
|
|
copy(buf1, buf[off:])
|
|
buf1[m] = '\n'
|
|
if off += m; off >= len(alu) {
|
|
off -= len(alu)
|
|
}
|
|
n -= m
|
|
}
|
|
}
|
|
|
|
const (
|
|
fastaLookupSize = 4096
|
|
fastaLookupScale float64 = fastaLookupSize - 1
|
|
)
|
|
|
|
var fastaRand uint32 = 42
|
|
|
|
type fastaAcid struct {
|
|
sym byte
|
|
prob float64
|
|
cprob float64
|
|
next *fastaAcid
|
|
}
|
|
|
|
func fastaComputeLookup(acid []fastaAcid) *[fastaLookupSize]*fastaAcid {
|
|
var lookup [fastaLookupSize]*fastaAcid
|
|
var p float64
|
|
for i := range acid {
|
|
p += acid[i].prob
|
|
acid[i].cprob = p * fastaLookupScale
|
|
if i > 0 {
|
|
acid[i-1].next = &acid[i]
|
|
}
|
|
}
|
|
acid[len(acid)-1].cprob = 1.0 * fastaLookupScale
|
|
|
|
j := 0
|
|
for i := range lookup {
|
|
for acid[j].cprob < float64(i) {
|
|
j++
|
|
}
|
|
lookup[i] = &acid[j]
|
|
}
|
|
|
|
return &lookup
|
|
}
|
|
|
|
func fastaRandom(out *fastaBuffer, acid []fastaAcid, n int) {
|
|
const (
|
|
IM = 139968
|
|
IA = 3877
|
|
IC = 29573
|
|
)
|
|
lookup := fastaComputeLookup(acid)
|
|
for n > 0 {
|
|
m := n
|
|
if m > fastaLine {
|
|
m = fastaLine
|
|
}
|
|
buf := out.NextWrite(m + 1)
|
|
f := fastaLookupScale / IM
|
|
myrand := fastaRand
|
|
for i := 0; i < m; i++ {
|
|
myrand = (myrand*IA + IC) % IM
|
|
r := float64(int(myrand)) * f
|
|
a := lookup[int(r)]
|
|
for a.cprob < r {
|
|
a = a.next
|
|
}
|
|
buf[i] = a.sym
|
|
}
|
|
fastaRand = myrand
|
|
buf[m] = '\n'
|
|
n -= m
|
|
}
|
|
}
|