瀏覽代碼

Use atomics for counters and gauges.

Massive memory savings.  Theoretically massive context switching savings.
Richard Crowley 14 年之前
父節點
當前提交
9192d930ec
共有 3 個文件被更改,包括 15 次插入37 次删除
  1. 1 1
      README.md
  2. 8 20
      counter.go
  3. 6 16
      gauge.go

+ 1 - 1
README.md

@@ -1,7 +1,7 @@
 go-metrics
 ==========
 
-TODO
+TODO This code is not safe on 32-bit architectures.
 
 Memory usage
 ------------

+ 8 - 20
counter.go

@@ -1,5 +1,7 @@
 package metrics
 
+import "sync/atomic"
+
 type Counter interface {
 	Clear()
 	Count() int64
@@ -8,39 +10,25 @@ type Counter interface {
 }
 
 type counter struct {
-	in, out chan int64
-	reset chan bool
+	count int64
 }
 
 func NewCounter() Counter {
-	c := &counter{make(chan int64), make(chan int64), make(chan bool)}
-	go c.arbiter()
-	return c
+	return &counter{0}
 }
 
 func (c *counter) Clear() {
-	c.reset <- true
+	c.count = 0
 }
 
 func (c *counter) Count() int64 {
-	return <-c.out
+	return c.count
 }
 
 func (c *counter) Dec(i int64) {
-	c.in <- -i
+	atomic.AddInt64(&c.count, -i)
 }
 
 func (c *counter) Inc(i int64) {
-	c.in <- i
-}
-
-func (c *counter) arbiter() {
-	var count int64
-	for {
-		select {
-		case i := <-c.in: count += i
-		case c.out <- count:
-		case <-c.reset: count = 0
-		}
-	}
+	atomic.AddInt64(&c.count, i)
 }

+ 6 - 16
gauge.go

@@ -1,34 +1,24 @@
 package metrics
 
+import "sync/atomic"
+
 type Gauge interface {
 	Update(int64)
 	Value() int64
 }
 
 type gauge struct {
-	in, out chan int64
+	value int64
 }
 
 func NewGauge() Gauge {
-	g := &gauge{make(chan int64), make(chan int64)}
-	go g.arbiter()
-	return g
+	return &gauge{0}
 }
 
 func (g *gauge) Update(v int64) {
-	g.in <- v
+	atomic.AddInt64(&g.value, v)
 }
 
 func (g *gauge) Value() int64 {
-	return <-g.out
-}
-
-func (g *gauge) arbiter() {
-	var value int64
-	for {
-		select {
-		case v := <-g.in: value = v
-		case g.out <- value:
-		}
-	}
+	return g.value
 }