|
|
@@ -0,0 +1,73 @@
|
|
|
+// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of
|
|
|
+// this source code is governed by a BSD-style license that can be found in the
|
|
|
+// LICENSE file.
|
|
|
+
|
|
|
+// Require 1.7 for sub-bencmarks
|
|
|
+// +build go1.7
|
|
|
+
|
|
|
+package websocket
|
|
|
+
|
|
|
+import (
|
|
|
+ "fmt"
|
|
|
+ "testing"
|
|
|
+)
|
|
|
+
|
|
|
+func maskBytesByByte(key [4]byte, pos int, b []byte) int {
|
|
|
+ for i := range b {
|
|
|
+ b[i] ^= key[pos&3]
|
|
|
+ pos++
|
|
|
+ }
|
|
|
+ return pos & 3
|
|
|
+}
|
|
|
+
|
|
|
+func notzero(b []byte) int {
|
|
|
+ for i := range b {
|
|
|
+ if b[i] != 0 {
|
|
|
+ return i
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return -1
|
|
|
+}
|
|
|
+
|
|
|
+func TestMaskBytes(t *testing.T) {
|
|
|
+ key := [4]byte{1, 2, 3, 4}
|
|
|
+ for size := 1; size <= 1024; size++ {
|
|
|
+ for align := 0; align < wordSize; align++ {
|
|
|
+ for pos := 0; pos < 4; pos++ {
|
|
|
+ b := make([]byte, size+align)[align:]
|
|
|
+ maskBytes(key, pos, b)
|
|
|
+ maskBytesByByte(key, pos, b)
|
|
|
+ if i := notzero(b); i >= 0 {
|
|
|
+ t.Errorf("size:%d, align:%d, pos:%d, offset:%d", size, align, pos, i)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func BenchmarkMaskBytes(b *testing.B) {
|
|
|
+ for _, size := range []int{2, 4, 8, 16, 32, 512, 1024} {
|
|
|
+ b.Run(fmt.Sprintf("size-%d", size), func(b *testing.B) {
|
|
|
+ for _, align := range []int{wordSize / 2} {
|
|
|
+ b.Run(fmt.Sprintf("align-%d", align), func(b *testing.B) {
|
|
|
+ for _, fn := range []struct {
|
|
|
+ name string
|
|
|
+ fn func(key [4]byte, pos int, b []byte) int
|
|
|
+ }{
|
|
|
+ {"byte", maskBytesByByte},
|
|
|
+ {"word", maskBytes},
|
|
|
+ } {
|
|
|
+ b.Run(fn.name, func(b *testing.B) {
|
|
|
+ key := newMaskKey()
|
|
|
+ data := make([]byte, size+align)[align:]
|
|
|
+ for i := 0; i < b.N; i++ {
|
|
|
+ fn.fn(key, 0, data)
|
|
|
+ }
|
|
|
+ b.SetBytes(int64(len(data)))
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|