github.com/sunvim/utils@v0.1.0/linear_ac/linear_ac_bench_test.go (about)

     1  // reference to
     2  // https://github.com/crazybie/linear_ac
     3  
     4  package linear_ac
     5  
     6  import (
     7  	"fmt"
     8  	"runtime"
     9  	"sync"
    10  	"sync/atomic"
    11  	"testing"
    12  	"time"
    13  )
    14  
    15  var (
    16  	totalTasks        = 100000
    17  	totalGoroutines   = 500
    18  	busyGoroutineId   = 1
    19  	busyGoroutineLoop = 1000
    20  )
    21  
    22  var largeConfigData []*PbDataEx
    23  
    24  func makeGlobalData() {
    25  	if largeConfigData == nil {
    26  		largeConfigData = make([]*PbDataEx, 100000)
    27  		for i := range largeConfigData {
    28  			largeConfigData[i] = makeData(i)
    29  		}
    30  	}
    31  }
    32  
    33  func Dispatch(genTasks func(chan func(int))) {
    34  
    35  	wait := sync.WaitGroup{}
    36  	wait.Add(totalGoroutines)
    37  	queue := make(chan func(int), totalGoroutines)
    38  	maxLatency, totalLatency := int64(0), int64(0)
    39  	cnt := int64(0)
    40  
    41  	for i := 0; i < totalGoroutines; i++ {
    42  		go func(routineId int) {
    43  			for task := range queue {
    44  
    45  				s := time.Now().UnixNano()
    46  				task(routineId)
    47  				elapsed := time.Now().UnixNano() - s
    48  
    49  				atomic.AddInt64(&totalLatency, elapsed)
    50  				atomic.AddInt64(&cnt, 1)
    51  				if elapsed > atomic.LoadInt64(&maxLatency) {
    52  					atomic.StoreInt64(&maxLatency, elapsed)
    53  				}
    54  			}
    55  			wait.Done()
    56  		}(i)
    57  	}
    58  
    59  	genTasks(queue)
    60  	close(queue)
    61  	wait.Wait()
    62  
    63  	fmt.Printf(">> Latency: max=%vms, avg=%vms.\n", maxLatency/1000/1000, totalLatency/cnt/1000/1000)
    64  }
    65  
    66  func Benchmark_LinearAc(t *testing.B) {
    67  	DbgMode = false
    68  	chunkPool.reserve(1600)
    69  	makeGlobalData()
    70  	runtime.GC()
    71  	t.StartTimer()
    72  
    73  	Dispatch(func(queue chan func(int)) {
    74  		for i := 0; i < totalTasks; i++ {
    75  			queue <- func(routine int) {
    76  
    77  				subLoop := 1
    78  				if routine == busyGoroutineId {
    79  					subLoop = busyGoroutineLoop
    80  				}
    81  
    82  				for n := 0; n < subLoop; n++ {
    83  					ac := BindNew()
    84  					_ = makeDataAc(n)
    85  					ac.Release()
    86  				}
    87  			}
    88  		}
    89  	})
    90  
    91  	acPool.clear()
    92  	chunkPool.clear()
    93  }
    94  
    95  func Benchmark_buildInAc(t *testing.B) {
    96  	makeGlobalData()
    97  	runtime.GC()
    98  	t.StartTimer()
    99  
   100  	Dispatch(func(c chan func(int)) {
   101  		for i := 0; i < totalTasks; i++ {
   102  			c <- func(routine int) {
   103  
   104  				subLoop := 1
   105  				if routine == busyGoroutineId {
   106  					subLoop = busyGoroutineLoop
   107  				}
   108  
   109  				for n := 0; n < subLoop; n++ {
   110  					_ = makeData(n)
   111  				}
   112  			}
   113  		}
   114  	})
   115  }
   116  
   117  type PbItemEx struct {
   118  	Id1     *int
   119  	Id2     *int
   120  	Id3     *int
   121  	Id4     *int
   122  	Id5     *int
   123  	Id6     *int
   124  	Id7     *int
   125  	Id8     *int
   126  	Id9     *int
   127  	Id10    *int
   128  	Price   *int
   129  	Class   *int
   130  	Name1   *string
   131  	Active  *bool
   132  	EnumVal *EnumA
   133  }
   134  
   135  type PbDataEx struct {
   136  	Age1    *int
   137  	Age2    *int
   138  	Age3    *int
   139  	Age4    *int
   140  	Age5    *int
   141  	Age6    *int
   142  	Age7    *int
   143  	Age8    *int
   144  	Age9    *int
   145  	Age10   *int
   146  	Items1  []*PbItemEx
   147  	Items2  []*PbItemEx
   148  	Items3  []*PbItemEx
   149  	Items4  []*PbItemEx
   150  	Items5  []*PbItemEx
   151  	Items6  []*PbItemEx
   152  	Items7  []*PbItemEx
   153  	Items8  []*PbItemEx
   154  	Items9  []*PbItemEx
   155  	InUse1  *PbItemEx
   156  	InUse2  *PbItemEx
   157  	InUse3  *PbItemEx
   158  	InUse4  *PbItemEx
   159  	InUse5  *PbItemEx
   160  	InUse6  *PbItemEx
   161  	InUse7  *PbItemEx
   162  	InUse8  *PbItemEx
   163  	InUse9  *PbItemEx
   164  	InUse10 *PbItemEx
   165  }
   166  
   167  var newInt = func(v int) *int { return &v }
   168  var newStr = func(v string) *string { return &v }
   169  var newBool = func(v bool) *bool { return &v }
   170  var newEnum = func(v EnumA) *EnumA { return &v }
   171  
   172  var makeItem = func(j int) *PbItemEx {
   173  	item := &PbItemEx{
   174  		Id1:     newInt(2 + j),
   175  		Id2:     newInt(2 + j),
   176  		Id3:     newInt(2 + j),
   177  		Id4:     newInt(2 + j),
   178  		Id5:     newInt(2 + j),
   179  		Id6:     newInt(2 + j),
   180  		Id7:     newInt(2 + j),
   181  		Id8:     newInt(2 + j),
   182  		Id9:     newInt(2 + j),
   183  		Id10:    newInt(2 + j),
   184  		Price:   newInt(100 + j),
   185  		Class:   newInt(3 + j),
   186  		Name1:   newStr("name"),
   187  		Active:  newBool(true),
   188  		EnumVal: newEnum(EnumVal2),
   189  	}
   190  	return item
   191  }
   192  
   193  var makeItemAc = func(j int, ac *Allocator) *PbItemEx {
   194  	return ac.NewCopy(&PbItemEx{
   195  		Id1:     ac.Int(2 + j),
   196  		Id2:     ac.Int(2 + j),
   197  		Id3:     ac.Int(2 + j),
   198  		Id4:     ac.Int(2 + j),
   199  		Id5:     ac.Int(2 + j),
   200  		Id6:     ac.Int(2 + j),
   201  		Id7:     ac.Int(2 + j),
   202  		Id8:     ac.Int(2 + j),
   203  		Id9:     ac.Int(2 + j),
   204  		Id10:    ac.Int(2 + j),
   205  		Price:   ac.Int(100 + j),
   206  		Class:   ac.Int(3 + j),
   207  		Name1:   ac.String("name"),
   208  		Active:  ac.Bool(true),
   209  		EnumVal: ac.Enum(EnumVal2).(*EnumA),
   210  	}).(*PbItemEx)
   211  }
   212  
   213  var itemLoop = 10
   214  
   215  func makeData(i int) *PbDataEx {
   216  	d := new(PbDataEx)
   217  	d.Age1 = newInt(11 + i)
   218  	d.Age2 = newInt(11 + i)
   219  	d.Age3 = newInt(11 + i)
   220  	d.Age4 = newInt(11 + i)
   221  	d.Age5 = newInt(11 + i)
   222  	d.Age6 = newInt(11 + i)
   223  	d.Age7 = newInt(11 + i)
   224  	d.Age8 = newInt(11 + i)
   225  	d.Age9 = newInt(11 + i)
   226  	d.Age10 = newInt(11 + i)
   227  
   228  	d.InUse1 = makeItem(i)
   229  	d.InUse2 = makeItem(i)
   230  	d.InUse3 = makeItem(i)
   231  	d.InUse4 = makeItem(i)
   232  	d.InUse5 = makeItem(i)
   233  	d.InUse6 = makeItem(i)
   234  	d.InUse7 = makeItem(i)
   235  	d.InUse8 = makeItem(i)
   236  	d.InUse9 = makeItem(i)
   237  	d.InUse10 = makeItem(i)
   238  
   239  	for j := 0; j < itemLoop; j++ {
   240  		d.Items1 = append(d.Items1, makeItem(j))
   241  	}
   242  	for j := 0; j < itemLoop; j++ {
   243  		d.Items2 = append(d.Items2, makeItem(j))
   244  	}
   245  	for j := 0; j < itemLoop; j++ {
   246  		d.Items3 = append(d.Items3, makeItem(j))
   247  	}
   248  	for j := 0; j < itemLoop; j++ {
   249  		d.Items4 = append(d.Items4, makeItem(j))
   250  	}
   251  	for j := 0; j < itemLoop; j++ {
   252  		d.Items5 = append(d.Items5, makeItem(j))
   253  	}
   254  	for j := 0; j < itemLoop; j++ {
   255  		d.Items6 = append(d.Items6, makeItem(j))
   256  	}
   257  	for j := 0; j < itemLoop; j++ {
   258  		d.Items7 = append(d.Items7, makeItem(j))
   259  	}
   260  	for j := 0; j < itemLoop; j++ {
   261  		d.Items8 = append(d.Items8, makeItem(j))
   262  	}
   263  	for j := 0; j < itemLoop; j++ {
   264  		d.Items9 = append(d.Items9, makeItem(j))
   265  	}
   266  	return d
   267  }
   268  
   269  func makeDataAc(i int) *PbDataEx {
   270  	ac := Get()
   271  
   272  	var d *PbDataEx
   273  	ac.New(&d)
   274  	d.Age1 = ac.Int(11 + i)
   275  	d.Age2 = ac.Int(11 + i)
   276  	d.Age3 = ac.Int(11 + i)
   277  	d.Age4 = ac.Int(11 + i)
   278  	d.Age5 = ac.Int(11 + i)
   279  	d.Age6 = ac.Int(11 + i)
   280  	d.Age7 = ac.Int(11 + i)
   281  	d.Age8 = ac.Int(11 + i)
   282  	d.Age9 = ac.Int(11 + i)
   283  	d.Age10 = ac.Int(11 + i)
   284  
   285  	d.InUse1 = makeItemAc(i, ac)
   286  	d.InUse2 = makeItemAc(i, ac)
   287  	d.InUse3 = makeItemAc(i, ac)
   288  	d.InUse4 = makeItemAc(i, ac)
   289  	d.InUse5 = makeItemAc(i, ac)
   290  	d.InUse6 = makeItemAc(i, ac)
   291  	d.InUse7 = makeItemAc(i, ac)
   292  	d.InUse8 = makeItemAc(i, ac)
   293  	d.InUse9 = makeItemAc(i, ac)
   294  	d.InUse10 = makeItemAc(i, ac)
   295  
   296  	for j := 0; j < itemLoop; j++ {
   297  		ac.SliceAppend(&d.Items1, makeItemAc(j, ac))
   298  	}
   299  	for j := 0; j < itemLoop; j++ {
   300  		ac.SliceAppend(&d.Items2, makeItemAc(j, ac))
   301  	}
   302  	for j := 0; j < itemLoop; j++ {
   303  		ac.SliceAppend(&d.Items3, makeItemAc(j, ac))
   304  	}
   305  	for j := 0; j < itemLoop; j++ {
   306  		ac.SliceAppend(&d.Items4, makeItemAc(j, ac))
   307  	}
   308  	for j := 0; j < itemLoop; j++ {
   309  		ac.SliceAppend(&d.Items5, makeItemAc(j, ac))
   310  	}
   311  	for j := 0; j < itemLoop; j++ {
   312  		ac.SliceAppend(&d.Items6, makeItemAc(j, ac))
   313  	}
   314  	for j := 0; j < itemLoop; j++ {
   315  		ac.SliceAppend(&d.Items7, makeItemAc(j, ac))
   316  	}
   317  	for j := 0; j < itemLoop; j++ {
   318  		ac.SliceAppend(&d.Items8, makeItemAc(j, ac))
   319  	}
   320  	for j := 0; j < itemLoop; j++ {
   321  		ac.SliceAppend(&d.Items9, makeItemAc(j, ac))
   322  	}
   323  	return d
   324  }