github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/queues/lscq/bench_test.go (about)

     1  package lscq
     2  
     3  import (
     4  	"sync/atomic"
     5  	"testing"
     6  
     7  	"github.com/songzhibin97/go-baseutils/internal/benchmark/linkedq"
     8  	"github.com/songzhibin97/go-baseutils/internal/benchmark/msq"
     9  	"github.com/songzhibin97/go-baseutils/sys/fastrand"
    10  )
    11  
    12  type uint64queue interface {
    13  	Enqueue(uint64) bool
    14  	Dequeue() (uint64, bool)
    15  }
    16  
    17  type benchTask struct {
    18  	name string
    19  	New  func() uint64queue
    20  }
    21  
    22  type faa int64
    23  
    24  func (data *faa) Enqueue(_ uint64) bool {
    25  	atomic.AddInt64((*int64)(data), 1)
    26  	return true
    27  }
    28  
    29  func (data *faa) Dequeue() (uint64, bool) {
    30  	atomic.AddInt64((*int64)(data), -1)
    31  	return 0, false
    32  }
    33  
    34  func BenchmarkDefault(b *testing.B) {
    35  	all := []benchTask{{
    36  		name: "LSCQ", New: func() uint64queue {
    37  			return NewUint64()
    38  		}}}
    39  	all = append(all, benchTask{
    40  		name: "LinkedQueue",
    41  		New: func() uint64queue {
    42  			return linkedq.New()
    43  		},
    44  	})
    45  	all = append(all, benchTask{
    46  		name: "MSQueue",
    47  		New: func() uint64queue {
    48  			return msq.New()
    49  		},
    50  	})
    51  	// all = append(all, benchTask{
    52  	// 	name: "FAA",
    53  	// 	New: func() uint64queue {
    54  	// 		return new(faa)
    55  	// 	},
    56  	// })
    57  	// all = append(all, benchTask{
    58  	// 	name: "channel",
    59  	// 	New: func() uint64queue {
    60  	// 		return newChannelQ(scqsize)
    61  	// 	},
    62  	// })
    63  	benchEnqueueOnly(b, all)
    64  	benchDequeueOnlyEmpty(b, all)
    65  	benchPair(b, all)
    66  	bench50Enqueue50Dequeue(b, all)
    67  	bench30Enqueue70Dequeue(b, all)
    68  	bench70Enqueue30Dequeue(b, all)
    69  }
    70  
    71  func reportalloc(b *testing.B) {
    72  	// b.SetBytes(8)
    73  	// b.ReportAllocs()
    74  }
    75  
    76  func benchPair(b *testing.B, benchTasks []benchTask) {
    77  	for _, v := range benchTasks {
    78  		b.Run("Pair/"+v.name, func(b *testing.B) {
    79  			q := v.New()
    80  			reportalloc(b)
    81  			b.ResetTimer()
    82  			b.RunParallel(func(pb *testing.PB) {
    83  				for pb.Next() {
    84  					q.Enqueue(uint64(fastrand.Uint32()))
    85  					q.Dequeue()
    86  				}
    87  			})
    88  		})
    89  	}
    90  }
    91  
    92  func bench50Enqueue50Dequeue(b *testing.B, benchTasks []benchTask) {
    93  	for _, v := range benchTasks {
    94  		b.Run("50Enqueue50Dequeue/"+v.name, func(b *testing.B) {
    95  			q := v.New()
    96  			b.ResetTimer()
    97  			reportalloc(b)
    98  			b.RunParallel(func(pb *testing.PB) {
    99  				for pb.Next() {
   100  					if fastrand.Uint32n(2) == 0 {
   101  						q.Enqueue(uint64(fastrand.Uint32()))
   102  					} else {
   103  						q.Dequeue()
   104  					}
   105  				}
   106  			})
   107  		})
   108  	}
   109  }
   110  
   111  func bench70Enqueue30Dequeue(b *testing.B, benchTasks []benchTask) {
   112  	for _, v := range benchTasks {
   113  		b.Run("70Enqueue30Dequeue/"+v.name, func(b *testing.B) {
   114  			q := v.New()
   115  			reportalloc(b)
   116  			b.ResetTimer()
   117  			b.RunParallel(func(pb *testing.PB) {
   118  				for pb.Next() {
   119  					if fastrand.Uint32n(10) > 2 {
   120  						q.Enqueue(uint64(fastrand.Uint32()))
   121  					} else {
   122  						q.Dequeue()
   123  					}
   124  				}
   125  			})
   126  		})
   127  	}
   128  }
   129  
   130  func bench30Enqueue70Dequeue(b *testing.B, benchTasks []benchTask) {
   131  	for _, v := range benchTasks {
   132  		b.Run("30Enqueue70Dequeue/"+v.name, func(b *testing.B) {
   133  			q := v.New()
   134  			reportalloc(b)
   135  			b.ResetTimer()
   136  			b.RunParallel(func(pb *testing.PB) {
   137  				for pb.Next() {
   138  					if fastrand.Uint32n(10) <= 2 {
   139  						q.Enqueue(uint64(fastrand.Uint32()))
   140  					} else {
   141  						q.Dequeue()
   142  					}
   143  				}
   144  			})
   145  		})
   146  	}
   147  }
   148  
   149  func benchEnqueueOnly(b *testing.B, benchTasks []benchTask) {
   150  	for _, v := range benchTasks {
   151  		b.Run("EnqueueOnly/"+v.name, func(b *testing.B) {
   152  			q := v.New()
   153  			reportalloc(b)
   154  			b.ResetTimer()
   155  			b.RunParallel(func(pb *testing.PB) {
   156  				for pb.Next() {
   157  					q.Enqueue(uint64(fastrand.Uint32()))
   158  				}
   159  			})
   160  		})
   161  	}
   162  }
   163  
   164  func benchDequeueOnlyEmpty(b *testing.B, benchTasks []benchTask) {
   165  	for _, v := range benchTasks {
   166  		b.Run("DequeueOnlyEmpty/"+v.name, func(b *testing.B) {
   167  			q := v.New()
   168  			reportalloc(b)
   169  			b.ResetTimer()
   170  			b.RunParallel(func(pb *testing.PB) {
   171  				for pb.Next() {
   172  					q.Dequeue()
   173  				}
   174  			})
   175  		})
   176  	}
   177  }