Home | History | Annotate | Download | only in go1
      1 // Copyright 2011 The Go Authors.  All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // This benchmark, taken from the shootout, tests array indexing
      6 // and array bounds elimination performance.
      7 
      8 package go1
      9 
     10 import (
     11 	"bufio"
     12 	"bytes"
     13 	"io/ioutil"
     14 	"testing"
     15 )
     16 
     17 var revCompTable = [256]uint8{
     18 	'A': 'T', 'a': 'T',
     19 	'C': 'G', 'c': 'G',
     20 	'G': 'C', 'g': 'C',
     21 	'T': 'A', 't': 'A',
     22 	'U': 'A', 'u': 'A',
     23 	'M': 'K', 'm': 'K',
     24 	'R': 'Y', 'r': 'Y',
     25 	'W': 'W', 'w': 'W',
     26 	'S': 'S', 's': 'S',
     27 	'Y': 'R', 'y': 'R',
     28 	'K': 'M', 'k': 'M',
     29 	'V': 'B', 'v': 'B',
     30 	'H': 'D', 'h': 'D',
     31 	'D': 'H', 'd': 'H',
     32 	'B': 'V', 'b': 'V',
     33 	'N': 'N', 'n': 'N',
     34 }
     35 
     36 func revcomp(data []byte) {
     37 	in := bufio.NewReader(bytes.NewBuffer(data))
     38 	out := ioutil.Discard
     39 	buf := make([]byte, 1024*1024)
     40 	line, err := in.ReadSlice('\n')
     41 	for err == nil {
     42 		out.Write(line)
     43 
     44 		// Accumulate reversed complement in buf[w:]
     45 		nchar := 0
     46 		w := len(buf)
     47 		for {
     48 			line, err = in.ReadSlice('\n')
     49 			if err != nil || line[0] == '>' {
     50 				break
     51 			}
     52 			line = line[0 : len(line)-1]
     53 			nchar += len(line)
     54 			if len(line)+nchar/60+128 >= w {
     55 				nbuf := make([]byte, len(buf)*5)
     56 				copy(nbuf[len(nbuf)-len(buf):], buf)
     57 				w += len(nbuf) - len(buf)
     58 				buf = nbuf
     59 			}
     60 
     61 			// This loop is the bottleneck.
     62 			for _, c := range line {
     63 				w--
     64 				buf[w] = revCompTable[c]
     65 			}
     66 		}
     67 
     68 		// Copy down to beginning of buffer, inserting newlines.
     69 		// The loop left room for the newlines and 128 bytes of padding.
     70 		i := 0
     71 		for j := w; j < len(buf); j += 60 {
     72 			n := copy(buf[i:i+60], buf[j:])
     73 			buf[i+n] = '\n'
     74 			i += n + 1
     75 		}
     76 		out.Write(buf[0:i])
     77 	}
     78 }
     79 
     80 func BenchmarkRevcomp(b *testing.B) {
     81 	b.SetBytes(int64(len(fastabytes)))
     82 	for i := 0; i < b.N; i++ {
     83 		revcomp(fastabytes)
     84 	}
     85 }
     86