Kaynağa Gözat

Use time.Ticker to avoid bajillions of threads.

time.Sleep is not scalable, as hilarious as that sounds.
Richard Crowley 14 yıl önce
ebeveyn
işleme
a31ebf206b
3 değiştirilmiş dosya ile 35 ekleme ve 23 silme
  1. 27 9
      README.md
  2. 3 3
      cmd/metrics-bench/metrics-bench.go
  3. 5 11
      meter.go

+ 27 - 9
README.md

@@ -240,20 +240,38 @@ VmSwap:        0 kB
 
 **10.2932 kB virtual, 9.99872 kB resident per histogram.**
 
-250 meters:
+1000 meters:
 
 ```
-VmPeak:  2148716 kB
-VmSize:  2148716 kB
+VmPeak:    84876 kB
+VmSize:    84876 kB
 VmLck:         0 kB
-VmHWM:      4088 kB
-VmRSS:      4088 kB
-VmData:  2141556 kB
+VmHWM:     25992 kB
+VmRSS:     25992 kB
+VmData:    77712 kB
 VmStk:       136 kB
-VmExe:      1036 kB
+VmExe:      1040 kB
 VmLib:      1848 kB
-VmPTE:      1076 kB
+VmPTE:        96 kB
 VmSwap:        0 kB
 ```
 
-**TODO 8424.448 kB virtual, 11.872 kB resident per meter.**
+**42.272 kB virtual, 24.872 kB resident per meter.**
+
+10000 meters:
+
+```
+VmPeak:   306956 kB
+VmSize:   306956 kB
+VmLck:         0 kB
+VmHWM:    245788 kB
+VmRSS:    245788 kB
+VmData:   299792 kB
+VmStk:       136 kB
+VmExe:      1040 kB
+VmLib:      1848 kB
+VmPTE:       532 kB
+VmSwap:        0 kB
+```
+
+**26.4352 kB virtual, 24.4668 kB resident per meter.**

+ 3 - 3
cmd/metrics-bench/metrics-bench.go

@@ -8,12 +8,12 @@ import (
 
 func main() {
 	r := metrics.NewRegistry()
-	for i := 0; i < 1000; i++ {
-		r.RegisterCounter(fmt.Sprintf("%d", i), metrics.NewCounter())
+	for i := 0; i < 10000; i++ {
+//		r.RegisterCounter(fmt.Sprintf("%d", i), metrics.NewCounter())
 //		r.RegisterGauge(fmt.Sprintf("%d", i), metrics.NewGauge())
 //		r.RegisterHistogram(fmt.Sprintf("%d", i), metrics.NewHistogram(metrics.NewUniformSample(1028)))
 //		r.RegisterHistogram(fmt.Sprintf("%d", i), metrics.NewHistogram(metrics.NewExpDecaySample(1028, 0.015)))
-//		r.RegisterMeter(fmt.Sprintf("%d", i), metrics.NewMeter())
+		r.RegisterMeter(fmt.Sprintf("%d", i), metrics.NewMeter())
 	}
 	time.Sleep(600e9)
 }

+ 5 - 11
meter.go

@@ -16,7 +16,8 @@ type Meter interface {
 type meter struct {
 	in chan int64
 	out chan meterV
-	reset, tick chan bool
+	reset chan bool
+	ticker *time.Ticker
 }
 
 type meterV struct {
@@ -28,10 +29,10 @@ func NewMeter() Meter {
 	m := &meter{
 		make(chan int64),
 		make(chan meterV),
-		make(chan bool), make(chan bool),
+		make(chan bool),
+		time.NewTicker(5e9),
 	}
 	go m.arbiter()
-	go m.ticker()
 	return m
 }
 
@@ -85,17 +86,10 @@ func (m *meter) arbiter() {
 			a5.Clear()
 			a15.Clear()
 			tsStart = time.Nanoseconds()
-		case <-m.tick:
+		case <-m.ticker.C:
 			a1.Tick()
 			a5.Tick()
 			a15.Tick()
 		}
 	}
 }
-
-func (m *meter) ticker() {
-	for {
-		time.Sleep(5e9)
-		m.tick <- true
-	}
-}