github.com/alphadose/zenq/v2@v2.8.4/benchmarks/simple/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	"github.com/alphadose/zenq/v2"
     8  )
     9  
    10  // Example item which we will be writing to and reading from the queue
    11  type Payload struct {
    12  	first   byte
    13  	second  int64
    14  	third   float64
    15  	fourth  string
    16  	fifth   complex64
    17  	sixth   []rune
    18  	seventh bool
    19  }
    20  
    21  func NewPayload() *Payload {
    22  	return &Payload{
    23  		first:  1,
    24  		second: 2,
    25  		third:  3.0,
    26  		fourth: "4",
    27  		fifth:  3 + 4i,
    28  		sixth:  []rune("🐈⚔️👍🌏💥🦖"),
    29  	}
    30  }
    31  
    32  const (
    33  	bufferSize = 1 << 12
    34  )
    35  
    36  var (
    37  	pl Payload = *NewPayload()
    38  
    39  	currSize uint64 = throughput[0]
    40  
    41  	// input batch size
    42  	throughput = []uint64{60, 600, 6e3, 6e6, 6e8}
    43  	// throughput = []uint64{5}
    44  
    45  	// Number of writers/producers which will be writing to the queue concurrently
    46  	numConcurrentWriters uint64 = 1
    47  
    48  	// native channel
    49  	ch chan Payload = make(chan Payload, bufferSize)
    50  
    51  	// ZenQ
    52  	zq *zenq.ZenQ[Payload] = zenq.New[Payload](bufferSize)
    53  )
    54  
    55  func validatePayload(param Payload) {
    56  	if param.first != pl.first || param.second != pl.second || param.third != pl.third || param.fourth != pl.fourth || param.fifth != pl.fifth || len(param.sixth) != len(pl.sixth) || param.seventh != pl.seventh {
    57  		panic("Loss of data integrity")
    58  	}
    59  }
    60  
    61  func chanProducer() {
    62  	epochs := currSize / numConcurrentWriters
    63  	for i := uint64(0); i < epochs; i++ {
    64  		ch <- pl
    65  	}
    66  }
    67  
    68  func chanConsumer() {
    69  	for i := uint64(0); i < currSize; i++ {
    70  		validatePayload(<-ch)
    71  	}
    72  }
    73  
    74  func chanRunner() {
    75  	for i := uint64(0); i < numConcurrentWriters; i++ {
    76  		go chanProducer()
    77  	}
    78  	chanConsumer()
    79  }
    80  
    81  func zenqProducer() {
    82  	epochs := currSize / numConcurrentWriters
    83  	for i := uint64(0); i < epochs; i++ {
    84  		zq.Write(pl)
    85  	}
    86  }
    87  
    88  func zenqConsumer() {
    89  	var data Payload
    90  	for i := uint64(0); i < currSize; i++ {
    91  		data, _ = zq.Read()
    92  		validatePayload(data)
    93  	}
    94  }
    95  
    96  func zenqRunner() {
    97  	for i := uint64(0); i < numConcurrentWriters; i++ {
    98  		go zenqProducer()
    99  	}
   100  	zenqConsumer()
   101  }
   102  
   103  func measureTime(callback func(), runnerName string) {
   104  	var startTime time.Time = time.Now()
   105  	callback()
   106  	fmt.Printf("%s Runner completed transfer in: %v\n", runnerName, time.Since(startTime))
   107  }
   108  
   109  // drain the channel and zenQ
   110  func cleanup() {
   111  	for len(ch) > 0 {
   112  		<-ch
   113  	}
   114  	zq.Reset()
   115  }
   116  
   117  func main() {
   118  	cleanup()
   119  	for _, tput := range throughput {
   120  		currSize = tput
   121  		fmt.Printf("With Input Batch Size: %d and Num Concurrent Writers: %d\n", currSize, numConcurrentWriters)
   122  		fmt.Print("\n")
   123  
   124  		// Run tests
   125  		measureTime(chanRunner, "Native Channel")
   126  		measureTime(zenqRunner, "ZenQ")
   127  		fmt.Print("====================================================================\n\n")
   128  	}
   129  }