github.com/macb/etcd@v0.3.1-0.20140227003422-a60481c6b1a0/store/store_bench_test.go (about)

     1  /*
     2  Copyright 2014 CoreOS Inc.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8       http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package store
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"runtime"
    23  	"testing"
    24  )
    25  
    26  func BenchmarkStoreSet128Bytes(b *testing.B) {
    27  	benchStoreSet(b, 128, nil)
    28  }
    29  
    30  func BenchmarkStoreSet1024Bytes(b *testing.B) {
    31  	benchStoreSet(b, 1024, nil)
    32  }
    33  
    34  func BenchmarkStoreSet4096Bytes(b *testing.B) {
    35  	benchStoreSet(b, 4096, nil)
    36  }
    37  
    38  func BenchmarkStoreSetWithJson128Bytes(b *testing.B) {
    39  	benchStoreSet(b, 128, json.Marshal)
    40  }
    41  
    42  func BenchmarkStoreSetWithJson1024Bytes(b *testing.B) {
    43  	benchStoreSet(b, 1024, json.Marshal)
    44  }
    45  
    46  func BenchmarkStoreSetWithJson4096Bytes(b *testing.B) {
    47  	benchStoreSet(b, 4096, json.Marshal)
    48  }
    49  
    50  func BenchmarkStoreDelete(b *testing.B) {
    51  	b.StopTimer()
    52  
    53  	s := newStore()
    54  	kvs, _ := generateNRandomKV(b.N, 128)
    55  
    56  	memStats := new(runtime.MemStats)
    57  	runtime.GC()
    58  	runtime.ReadMemStats(memStats)
    59  
    60  	for i := 0; i < b.N; i++ {
    61  		_, err := s.Set(kvs[i][0], false, kvs[i][1], Permanent)
    62  		if err != nil {
    63  			panic(err)
    64  		}
    65  	}
    66  
    67  	setMemStats := new(runtime.MemStats)
    68  	runtime.GC()
    69  	runtime.ReadMemStats(setMemStats)
    70  
    71  	b.StartTimer()
    72  
    73  	for i := range kvs {
    74  		s.Delete(kvs[i][0], false, false)
    75  	}
    76  
    77  	b.StopTimer()
    78  
    79  	// clean up
    80  	e, err := s.Get("/", false, false)
    81  	if err != nil {
    82  		panic(err)
    83  	}
    84  
    85  	for _, n := range e.Node.Nodes {
    86  		_, err := s.Delete(n.Key, true, true)
    87  		if err != nil {
    88  			panic(err)
    89  		}
    90  	}
    91  	s.WatcherHub.EventHistory = nil
    92  
    93  	deleteMemStats := new(runtime.MemStats)
    94  	runtime.GC()
    95  	runtime.ReadMemStats(deleteMemStats)
    96  
    97  	fmt.Printf("\nBefore set Alloc: %v; After set Alloc: %v, After delete Alloc: %v\n",
    98  		memStats.Alloc/1000, setMemStats.Alloc/1000, deleteMemStats.Alloc/1000)
    99  }
   100  
   101  func BenchmarkWatch(b *testing.B) {
   102  	b.StopTimer()
   103  	s := newStore()
   104  	kvs, _ := generateNRandomKV(b.N, 128)
   105  	b.StartTimer()
   106  
   107  	memStats := new(runtime.MemStats)
   108  	runtime.GC()
   109  	runtime.ReadMemStats(memStats)
   110  
   111  	for i := 0; i < b.N; i++ {
   112  		w, _ := s.Watch(kvs[i][0], false, false, 0)
   113  
   114  		e := newEvent("set", kvs[i][0], uint64(i+1), uint64(i+1))
   115  		s.WatcherHub.notify(e)
   116  		<-w.EventChan
   117  		s.CurrentIndex++
   118  	}
   119  
   120  	s.WatcherHub.EventHistory = nil
   121  	afterMemStats := new(runtime.MemStats)
   122  	runtime.GC()
   123  	runtime.ReadMemStats(afterMemStats)
   124  	fmt.Printf("\nBefore Alloc: %v; After Alloc: %v\n",
   125  		memStats.Alloc/1000, afterMemStats.Alloc/1000)
   126  }
   127  
   128  func BenchmarkWatchWithSet(b *testing.B) {
   129  	b.StopTimer()
   130  	s := newStore()
   131  	kvs, _ := generateNRandomKV(b.N, 128)
   132  	b.StartTimer()
   133  
   134  	for i := 0; i < b.N; i++ {
   135  		w, _ := s.Watch(kvs[i][0], false, false, 0)
   136  
   137  		s.Set(kvs[i][0], false, "test", Permanent)
   138  		<-w.EventChan
   139  	}
   140  }
   141  
   142  func BenchmarkWatchWithSetBatch(b *testing.B) {
   143  	b.StopTimer()
   144  	s := newStore()
   145  	kvs, _ := generateNRandomKV(b.N, 128)
   146  	b.StartTimer()
   147  
   148  	watchers := make([]*Watcher, b.N)
   149  
   150  	for i := 0; i < b.N; i++ {
   151  		watchers[i], _ = s.Watch(kvs[i][0], false, false, 0)
   152  	}
   153  
   154  	for i := 0; i < b.N; i++ {
   155  		s.Set(kvs[i][0], false, "test", Permanent)
   156  	}
   157  
   158  	for i := 0; i < b.N; i++ {
   159  		<-watchers[i].EventChan
   160  	}
   161  
   162  }
   163  
   164  func BenchmarkWatchOneKey(b *testing.B) {
   165  	s := newStore()
   166  	watchers := make([]*Watcher, b.N)
   167  
   168  	for i := 0; i < b.N; i++ {
   169  		watchers[i], _ = s.Watch("/foo", false, false, 0)
   170  	}
   171  
   172  	s.Set("/foo", false, "", Permanent)
   173  
   174  	for i := 0; i < b.N; i++ {
   175  		<-watchers[i].EventChan
   176  	}
   177  }
   178  
   179  func benchStoreSet(b *testing.B, valueSize int, process func(interface{}) ([]byte, error)) {
   180  	s := newStore()
   181  	b.StopTimer()
   182  	kvs, size := generateNRandomKV(b.N, valueSize)
   183  	b.StartTimer()
   184  
   185  	for i := 0; i < b.N; i++ {
   186  		resp, err := s.Set(kvs[i][0], false, kvs[i][1], Permanent)
   187  		if err != nil {
   188  			panic(err)
   189  		}
   190  
   191  		if process != nil {
   192  			_, err = process(resp)
   193  			if err != nil {
   194  				panic(err)
   195  			}
   196  		}
   197  	}
   198  
   199  	kvs = nil
   200  	b.StopTimer()
   201  	memStats := new(runtime.MemStats)
   202  	runtime.GC()
   203  	runtime.ReadMemStats(memStats)
   204  	fmt.Printf("\nAlloc: %vKB; Data: %vKB; Kvs: %v; Alloc/Data:%v\n",
   205  		memStats.Alloc/1000, size/1000, b.N, memStats.Alloc/size)
   206  }
   207  
   208  func generateNRandomKV(n int, valueSize int) ([][]string, uint64) {
   209  	var size uint64
   210  	kvs := make([][]string, n)
   211  	bytes := make([]byte, valueSize)
   212  
   213  	for i := 0; i < n; i++ {
   214  		kvs[i] = make([]string, 2)
   215  		kvs[i][0] = fmt.Sprintf("/%010d/%010d/%010d", n, n, n)
   216  		kvs[i][1] = string(bytes)
   217  		size = size + uint64(len(kvs[i][0])) + uint64(len(kvs[i][1]))
   218  	}
   219  
   220  	return kvs, size
   221  }