github.com/andy2046/gopie@v0.7.0/pkg/multilane/multilane_test.go (about)

     1  package multilane_test
     2  
     3  import (
     4  	. "github.com/andy2046/gopie/pkg/multilane"
     5  	"go.uber.org/goleak"
     6  	"runtime"
     7  	"sync"
     8  	"testing"
     9  	"time"
    10  )
    11  
    12  var config = Config{
    13  	LaneWidth: 8,
    14  	QueueSize: 1024,
    15  }
    16  
    17  func BenchmarkMultiLane_Blocking(b *testing.B) {
    18  	var (
    19  		m                            = New(config)
    20  		wgPut, wgGet                 sync.WaitGroup
    21  		concurrentGet, concurrentPut = 8, 8
    22  	)
    23  	wgPut.Add(concurrentPut)
    24  	wgGet.Add(concurrentGet)
    25  	type T struct {
    26  		i int
    27  	}
    28  	var v = T{5}
    29  	b.ResetTimer()
    30  	for c := 0; c < concurrentPut; c++ {
    31  		go func(n int) {
    32  			// runtime.LockOSThread()
    33  			for i := 0; i < n; i++ {
    34  				m.Put(&v)
    35  			}
    36  			wgPut.Done()
    37  		}(b.N/concurrentPut + 1)
    38  	}
    39  	for c := 0; c < concurrentGet; c++ {
    40  		go func(n int) {
    41  			// runtime.LockOSThread()
    42  			var v *T
    43  			for i := 0; m.Get(&v); i++ {
    44  				_ = *v
    45  			}
    46  			wgGet.Done()
    47  		}(b.N/concurrentGet + 1)
    48  	}
    49  
    50  	wgPut.Wait()
    51  	m.Close()
    52  	wgGet.Wait()
    53  }
    54  
    55  func BenchmarkMultiLane_BlockingLane(b *testing.B) {
    56  	var (
    57  		m                            = New(config)
    58  		wgPut, wgGet                 sync.WaitGroup
    59  		concurrentGet, concurrentPut = 8, 8
    60  	)
    61  	wgPut.Add(concurrentPut)
    62  	wgGet.Add(concurrentGet)
    63  	type T struct {
    64  		i int
    65  	}
    66  	var v = T{5}
    67  	b.ResetTimer()
    68  	for c := 0; c < concurrentPut; c++ {
    69  		go func(n int, lane uint32) {
    70  			// runtime.LockOSThread()
    71  			for i := 0; i < n; i++ {
    72  				m.PutLane(lane, &v)
    73  			}
    74  			wgPut.Done()
    75  		}(b.N/concurrentPut+1, uint32(c))
    76  	}
    77  	for c := 0; c < concurrentGet; c++ {
    78  		go func(n int, lane uint32) {
    79  			// runtime.LockOSThread()
    80  			var v *T
    81  			for i := 0; m.GetLane(lane, &v); i++ {
    82  				_ = *v
    83  			}
    84  			wgGet.Done()
    85  		}(b.N/concurrentGet+1, uint32(c))
    86  	}
    87  
    88  	wgPut.Wait()
    89  	m.Close()
    90  	wgGet.Wait()
    91  }
    92  
    93  func BenchmarkMultiLane_Blocking2(b *testing.B) {
    94  	var (
    95  		m                            = New(config)
    96  		wgPut, wgGet                 sync.WaitGroup
    97  		concurrentGet, concurrentPut = 8, 8
    98  	)
    99  	wgPut.Add(concurrentPut)
   100  	wgGet.Add(concurrentGet)
   101  	type T struct {
   102  		i int
   103  	}
   104  	p := runtime.GOMAXPROCS(concurrentGet + concurrentPut)
   105  	var v = T{5}
   106  	b.ResetTimer()
   107  	for c := 0; c < concurrentPut; c++ {
   108  		go func(n int) {
   109  			for i := 0; i < n; i++ {
   110  				m.Put(&v)
   111  			}
   112  			wgPut.Done()
   113  		}(b.N/concurrentPut + 1)
   114  	}
   115  	for c := 0; c < concurrentGet; c++ {
   116  		go func(n int) {
   117  			var v *T
   118  			for i := 0; m.Get(&v); i++ {
   119  				_ = *v
   120  			}
   121  			wgGet.Done()
   122  		}(b.N/concurrentGet + 1)
   123  	}
   124  
   125  	wgPut.Wait()
   126  	m.Close()
   127  	wgGet.Wait()
   128  	runtime.GOMAXPROCS(p)
   129  }
   130  
   131  func BenchmarkMultiLane_BlockingLane2(b *testing.B) {
   132  	var (
   133  		m                            = New(config)
   134  		wgPut, wgGet                 sync.WaitGroup
   135  		concurrentGet, concurrentPut = 8, 8
   136  	)
   137  	wgPut.Add(concurrentPut)
   138  	wgGet.Add(concurrentGet)
   139  	type T struct {
   140  		i int
   141  	}
   142  	p := runtime.GOMAXPROCS(concurrentGet + concurrentPut)
   143  	var v = T{5}
   144  	b.ResetTimer()
   145  	for c := 0; c < concurrentPut; c++ {
   146  		go func(n int, lane uint32) {
   147  			for i := 0; i < n; i++ {
   148  				m.PutLane(lane, &v)
   149  			}
   150  			wgPut.Done()
   151  		}(b.N/concurrentPut+1, uint32(c))
   152  	}
   153  	for c := 0; c < concurrentGet; c++ {
   154  		go func(n int, lane uint32) {
   155  			var v *T
   156  			for i := 0; m.GetLane(lane, &v); i++ {
   157  				_ = *v
   158  			}
   159  			wgGet.Done()
   160  		}(b.N/concurrentGet+1, uint32(c))
   161  	}
   162  
   163  	wgPut.Wait()
   164  	m.Close()
   165  	wgGet.Wait()
   166  	runtime.GOMAXPROCS(p)
   167  }
   168  
   169  func TestMultiLane_Blocking(t *testing.T) {
   170  	defer goleak.VerifyNone(t)
   171  	const N = 1000
   172  	var m = New(Config{
   173  		LaneWidth: 2,
   174  		QueueSize: 8,
   175  	})
   176  	var wg sync.WaitGroup
   177  	wg.Add(2)
   178  	t1 := time.Now()
   179  	go func(n int) {
   180  		defer wg.Done()
   181  		for i := 0; i < n; i++ {
   182  			m.Put(int64(i))
   183  			time.Sleep(1 * time.Microsecond)
   184  		}
   185  		m.Close()
   186  	}(N)
   187  	go func(n int) {
   188  		defer wg.Done()
   189  		var v *int
   190  		for i := 0; m.Get(&v); i++ {
   191  			if i != *v {
   192  				t.Fatalf("Expected %d, but got %d", i, *v)
   193  				panic(i)
   194  			}
   195  		}
   196  	}(N)
   197  	wg.Wait()
   198  	t.Log(time.Since(t1))
   199  }