Consistently use Sleep in state-management examples
Consistently use `time.Sleep`, instead of `runtime.Gosched`, to ensure all goroutines can make progress. `Gosched` wasn't working in the playground (ref #149). Also stop trying to compare operation rates. This was tenuous given e.g. how short the programs ran for, and with the `Sleep`s we now expect the rates to be similar anyways.
This commit is contained in:
parent
94cba6875d
commit
6a58750728
@ -10,7 +10,6 @@ package main
|
||||
import "fmt"
|
||||
import "time"
|
||||
import "sync/atomic"
|
||||
import "runtime"
|
||||
|
||||
func main() {
|
||||
|
||||
@ -30,8 +29,8 @@ func main() {
|
||||
// `&` syntax.
|
||||
atomic.AddUint64(&ops, 1)
|
||||
|
||||
// Allow other goroutines to proceed.
|
||||
runtime.Gosched()
|
||||
// Wait a bit between increments.
|
||||
time.Sleep(time.Millisecond)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
ddfef8425eef64cfcb82799c9bddca4bfa9bbd29
|
||||
2h8nvrnaHP
|
||||
ce8821f1f4fd99d554ad6cde52403dd3b69bb70a
|
||||
8p48eFFxDZ
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Running the program shows that we executed about
|
||||
# 40,000 operations.
|
||||
$ go run atomic-counters.go
|
||||
ops: 40200
|
||||
ops: 41419
|
||||
|
||||
# Next we'll look at mutexes, another tool for managing
|
||||
# state.
|
||||
|
@ -8,7 +8,6 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@ -22,13 +21,14 @@ func main() {
|
||||
// This `mutex` will synchronize access to `state`.
|
||||
var mutex = &sync.Mutex{}
|
||||
|
||||
// To compare the mutex-based approach with another
|
||||
// we'll see later, `ops` will count how many
|
||||
// operations we perform against the state.
|
||||
var ops int64 = 0
|
||||
// We'll keep track of how many read and write
|
||||
// operations we do.
|
||||
var readOps uint64 = 0
|
||||
var writeOps uint64 = 0
|
||||
|
||||
// Here we start 100 goroutines to execute repeated
|
||||
// reads against the state.
|
||||
// reads against the state, once per millisecond in
|
||||
// each goroutine.
|
||||
for r := 0; r < 100; r++ {
|
||||
go func() {
|
||||
total := 0
|
||||
@ -39,22 +39,15 @@ func main() {
|
||||
// exclusive access to the `state`, read
|
||||
// the value at the chosen key,
|
||||
// `Unlock()` the mutex, and increment
|
||||
// the `ops` count.
|
||||
// the `readOps` count.
|
||||
key := rand.Intn(5)
|
||||
mutex.Lock()
|
||||
total += state[key]
|
||||
mutex.Unlock()
|
||||
atomic.AddInt64(&ops, 1)
|
||||
atomic.AddUint64(&readOps, 1)
|
||||
|
||||
// In order to ensure that this goroutine
|
||||
// doesn't starve the scheduler, we explicitly
|
||||
// yield after each operation with
|
||||
// `runtime.Gosched()`. This yielding is
|
||||
// handled automatically with e.g. every
|
||||
// channel operation and for blocking
|
||||
// calls like `time.Sleep`, but in this
|
||||
// case we need to do it manually.
|
||||
runtime.Gosched()
|
||||
// Wait a bit between reads.
|
||||
time.Sleep(time.Millisecond)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@ -69,8 +62,8 @@ func main() {
|
||||
mutex.Lock()
|
||||
state[key] = val
|
||||
mutex.Unlock()
|
||||
atomic.AddInt64(&ops, 1)
|
||||
runtime.Gosched()
|
||||
atomic.AddUint64(&writeOps, 1)
|
||||
time.Sleep(time.Millisecond)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@ -79,9 +72,11 @@ func main() {
|
||||
// `mutex` for a second.
|
||||
time.Sleep(time.Second)
|
||||
|
||||
// Take and report a final operations count.
|
||||
opsFinal := atomic.LoadInt64(&ops)
|
||||
fmt.Println("ops:", opsFinal)
|
||||
// Take and report final operation counts.
|
||||
readOpsFinal := atomic.LoadUint64(&readOps)
|
||||
fmt.Println("readOps:", readOpsFinal)
|
||||
writeOpsFinal := atomic.LoadUint64(&writeOps)
|
||||
fmt.Println("writeOps:", writeOpsFinal)
|
||||
|
||||
// With a final lock of `state`, show how it ended up.
|
||||
mutex.Lock()
|
||||
|
@ -1,2 +1,2 @@
|
||||
3ce8467418aa740ea6c930afac3985a943c76311
|
||||
kZrod-Rkos
|
||||
e82356cbb37143862b0a9bbc68856f4b272c4918
|
||||
a9Wky7k-Bw
|
||||
|
@ -1,9 +1,10 @@
|
||||
# Running the program shows that we executed about
|
||||
# 3,500,000 operations against our `mutex`-synchronized
|
||||
# 90,000 total operations against our `mutex`-synchronized
|
||||
# `state`.
|
||||
$ go run mutexes.go
|
||||
ops: 3598302
|
||||
state: map[1:38 4:98 2:23 3:85 0:44]
|
||||
readOps: 83285
|
||||
writeOps: 8320
|
||||
state: map[1:97 4:53 0:33 2:15 3:2]
|
||||
|
||||
# Next we'll look at implementing this same state
|
||||
# management task using only goroutines and channels.
|
||||
|
@ -37,7 +37,8 @@ type writeOp struct {
|
||||
func main() {
|
||||
|
||||
// As before we'll count how many operations we perform.
|
||||
var ops int64 = 0
|
||||
var readOps uint64 = 0
|
||||
var writeOps uint64 = 0
|
||||
|
||||
// The `reads` and `writes` channels will be used by
|
||||
// other goroutines to issue read and write requests,
|
||||
@ -80,7 +81,8 @@ func main() {
|
||||
resp: make(chan int)}
|
||||
reads <- read
|
||||
<-read.resp
|
||||
atomic.AddInt64(&ops, 1)
|
||||
atomic.AddUint64(&readOps, 1)
|
||||
time.Sleep(time.Millisecond)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@ -96,7 +98,8 @@ func main() {
|
||||
resp: make(chan bool)}
|
||||
writes <- write
|
||||
<-write.resp
|
||||
atomic.AddInt64(&ops, 1)
|
||||
atomic.AddUint64(&writeOps, 1)
|
||||
time.Sleep(time.Millisecond)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@ -104,7 +107,9 @@ func main() {
|
||||
// Let the goroutines work for a second.
|
||||
time.Sleep(time.Second)
|
||||
|
||||
// Finally, capture and report the `ops` count.
|
||||
opsFinal := atomic.LoadInt64(&ops)
|
||||
fmt.Println("ops:", opsFinal)
|
||||
// Finally, capture and report the op counts.
|
||||
readOpsFinal := atomic.LoadUint64(&readOps)
|
||||
fmt.Println("readOps:", readOpsFinal)
|
||||
writeOpsFinal := atomic.LoadUint64(&writeOps)
|
||||
fmt.Println("writeOps:", writeOpsFinal)
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
603a70a77ed18db9da4f8c7911a92b87fd21400c
|
||||
-WqmiTr6ek
|
||||
c306add52c0752f0b3099eb669364fc4bdb74be1
|
||||
P4SrrlosMp
|
||||
|
@ -1,8 +1,9 @@
|
||||
# Running our program shows that the goroutine-based
|
||||
# state management example achieves about 800,000
|
||||
# operations per second.
|
||||
# state management example completes about 80,000
|
||||
# total operations.
|
||||
$ go run stateful-goroutines.go
|
||||
ops: 807434
|
||||
readOps: 71708
|
||||
writeOps: 7177
|
||||
|
||||
# For this particular case the goroutine-based approach
|
||||
# was a bit more involved than the mutex-based one. It
|
||||
|
@ -44,7 +44,7 @@ counters</em> accessed by multiple goroutines.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
<a href="http://play.golang.org/p/2h8nvrnaHP"><img title="Run code" src="play.png" class="run" /></a>
|
||||
<a href="http://play.golang.org/p/8p48eFFxDZ"><img title="Run code" src="play.png" class="run" /></a>
|
||||
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
|
||||
</pre></div>
|
||||
|
||||
@ -60,7 +60,6 @@ counters</em> accessed by multiple goroutines.</p>
|
||||
<div class="highlight"><pre><span class="kn">import</span> <span class="s">"fmt"</span>
|
||||
<span class="kn">import</span> <span class="s">"time"</span>
|
||||
<span class="kn">import</span> <span class="s">"sync/atomic"</span>
|
||||
<span class="kn">import</span> <span class="s">"runtime"</span>
|
||||
</pre></div>
|
||||
|
||||
</td>
|
||||
@ -127,12 +126,12 @@ address of our <code>ops</code> counter with the
|
||||
|
||||
<tr>
|
||||
<td class="docs">
|
||||
<p>Allow other goroutines to proceed.</p>
|
||||
<p>Wait a bit between increments.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<div class="highlight"><pre> <span class="nx">runtime</span><span class="p">.</span><span class="nx">Gosched</span><span class="p">()</span>
|
||||
<div class="highlight"><pre> <span class="nx">time</span><span class="p">.</span><span class="nx">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Millisecond</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}()</span>
|
||||
<span class="p">}</span>
|
||||
@ -187,7 +186,7 @@ fetch the value.</p>
|
||||
<td class="code leading">
|
||||
|
||||
<div class="highlight"><pre><span class="gp">$</span> go run atomic-counters.go
|
||||
<span class="go">ops: 40200</span>
|
||||
<span class="go">ops: 41419</span>
|
||||
</pre></div>
|
||||
|
||||
</td>
|
||||
|
@ -42,7 +42,7 @@ to safely access data across multiple goroutines.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
<a href="http://play.golang.org/p/kZrod-Rkos"><img title="Run code" src="play.png" class="run" /></a>
|
||||
<a href="http://play.golang.org/p/a9Wky7k-Bw"><img title="Run code" src="play.png" class="run" /></a>
|
||||
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
|
||||
</pre></div>
|
||||
|
||||
@ -58,7 +58,6 @@ to safely access data across multiple goroutines.</p>
|
||||
<div class="highlight"><pre><span class="kn">import</span> <span class="p">(</span>
|
||||
<span class="s">"fmt"</span>
|
||||
<span class="s">"math/rand"</span>
|
||||
<span class="s">"runtime"</span>
|
||||
<span class="s">"sync"</span>
|
||||
<span class="s">"sync/atomic"</span>
|
||||
<span class="s">"time"</span>
|
||||
@ -108,14 +107,14 @@ to safely access data across multiple goroutines.</p>
|
||||
|
||||
<tr>
|
||||
<td class="docs">
|
||||
<p>To compare the mutex-based approach with another
|
||||
we’ll see later, <code>ops</code> will count how many
|
||||
operations we perform against the state.</p>
|
||||
<p>We’ll keep track of how many read and write
|
||||
operations we do.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<div class="highlight"><pre> <span class="kd">var</span> <span class="nx">ops</span> <span class="kt">int64</span> <span class="p">=</span> <span class="mi">0</span>
|
||||
<div class="highlight"><pre> <span class="kd">var</span> <span class="nx">readOps</span> <span class="kt">uint64</span> <span class="p">=</span> <span class="mi">0</span>
|
||||
<span class="kd">var</span> <span class="nx">writeOps</span> <span class="kt">uint64</span> <span class="p">=</span> <span class="mi">0</span>
|
||||
</pre></div>
|
||||
|
||||
</td>
|
||||
@ -124,7 +123,8 @@ operations we perform against the state.</p>
|
||||
<tr>
|
||||
<td class="docs">
|
||||
<p>Here we start 100 goroutines to execute repeated
|
||||
reads against the state.</p>
|
||||
reads against the state, once per millisecond in
|
||||
each goroutine.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
@ -145,7 +145,7 @@ reads against the state.</p>
|
||||
exclusive access to the <code>state</code>, read
|
||||
the value at the chosen key,
|
||||
<code>Unlock()</code> the mutex, and increment
|
||||
the <code>ops</code> count.</p>
|
||||
the <code>readOps</code> count.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
@ -154,7 +154,7 @@ the <code>ops</code> count.</p>
|
||||
<span class="nx">mutex</span><span class="p">.</span><span class="nx">Lock</span><span class="p">()</span>
|
||||
<span class="nx">total</span> <span class="o">+=</span> <span class="nx">state</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span>
|
||||
<span class="nx">mutex</span><span class="p">.</span><span class="nx">Unlock</span><span class="p">()</span>
|
||||
<span class="nx">atomic</span><span class="p">.</span><span class="nx">AddInt64</span><span class="p">(</span><span class="o">&</span><span class="nx">ops</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||||
<span class="nx">atomic</span><span class="p">.</span><span class="nx">AddUint64</span><span class="p">(</span><span class="o">&</span><span class="nx">readOps</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</td>
|
||||
@ -162,19 +162,12 @@ the <code>ops</code> count.</p>
|
||||
|
||||
<tr>
|
||||
<td class="docs">
|
||||
<p>In order to ensure that this goroutine
|
||||
doesn’t starve the scheduler, we explicitly
|
||||
yield after each operation with
|
||||
<code>runtime.Gosched()</code>. This yielding is
|
||||
handled automatically with e.g. every
|
||||
channel operation and for blocking
|
||||
calls like <code>time.Sleep</code>, but in this
|
||||
case we need to do it manually.</p>
|
||||
<p>Wait a bit between reads.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<div class="highlight"><pre> <span class="nx">runtime</span><span class="p">.</span><span class="nx">Gosched</span><span class="p">()</span>
|
||||
<div class="highlight"><pre> <span class="nx">time</span><span class="p">.</span><span class="nx">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Millisecond</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}()</span>
|
||||
<span class="p">}</span>
|
||||
@ -199,8 +192,8 @@ using the same pattern we did for reads.</p>
|
||||
<span class="nx">mutex</span><span class="p">.</span><span class="nx">Lock</span><span class="p">()</span>
|
||||
<span class="nx">state</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="p">=</span> <span class="nx">val</span>
|
||||
<span class="nx">mutex</span><span class="p">.</span><span class="nx">Unlock</span><span class="p">()</span>
|
||||
<span class="nx">atomic</span><span class="p">.</span><span class="nx">AddInt64</span><span class="p">(</span><span class="o">&</span><span class="nx">ops</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||||
<span class="nx">runtime</span><span class="p">.</span><span class="nx">Gosched</span><span class="p">()</span>
|
||||
<span class="nx">atomic</span><span class="p">.</span><span class="nx">AddUint64</span><span class="p">(</span><span class="o">&</span><span class="nx">writeOps</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||||
<span class="nx">time</span><span class="p">.</span><span class="nx">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Millisecond</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}()</span>
|
||||
<span class="p">}</span>
|
||||
@ -225,13 +218,15 @@ using the same pattern we did for reads.</p>
|
||||
|
||||
<tr>
|
||||
<td class="docs">
|
||||
<p>Take and report a final operations count.</p>
|
||||
<p>Take and report final operation counts.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<div class="highlight"><pre> <span class="nx">opsFinal</span> <span class="o">:=</span> <span class="nx">atomic</span><span class="p">.</span><span class="nx">LoadInt64</span><span class="p">(</span><span class="o">&</span><span class="nx">ops</span><span class="p">)</span>
|
||||
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">"ops:"</span><span class="p">,</span> <span class="nx">opsFinal</span><span class="p">)</span>
|
||||
<div class="highlight"><pre> <span class="nx">readOpsFinal</span> <span class="o">:=</span> <span class="nx">atomic</span><span class="p">.</span><span class="nx">LoadUint64</span><span class="p">(</span><span class="o">&</span><span class="nx">readOps</span><span class="p">)</span>
|
||||
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">"readOps:"</span><span class="p">,</span> <span class="nx">readOpsFinal</span><span class="p">)</span>
|
||||
<span class="nx">writeOpsFinal</span> <span class="o">:=</span> <span class="nx">atomic</span><span class="p">.</span><span class="nx">LoadUint64</span><span class="p">(</span><span class="o">&</span><span class="nx">writeOps</span><span class="p">)</span>
|
||||
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">"writeOps:"</span><span class="p">,</span> <span class="nx">writeOpsFinal</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</td>
|
||||
@ -260,15 +255,16 @@ using the same pattern we did for reads.</p>
|
||||
<tr>
|
||||
<td class="docs">
|
||||
<p>Running the program shows that we executed about
|
||||
3,500,000 operations against our <code>mutex</code>-synchronized
|
||||
90,000 total operations against our <code>mutex</code>-synchronized
|
||||
<code>state</code>.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<div class="highlight"><pre><span class="gp">$</span> go run mutexes.go
|
||||
<span class="go">ops: 3598302</span>
|
||||
<span class="go">state: map[1:38 4:98 2:23 3:85 0:44]</span>
|
||||
<span class="go">readOps: 83285</span>
|
||||
<span class="go">writeOps: 8320</span>
|
||||
<span class="go">state: map[1:97 4:53 0:33 2:15 3:2]</span>
|
||||
</pre></div>
|
||||
|
||||
</td>
|
||||
|
@ -46,7 +46,7 @@ by exactly 1 goroutine.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
<a href="http://play.golang.org/p/-WqmiTr6ek"><img title="Run code" src="play.png" class="run" /></a>
|
||||
<a href="http://play.golang.org/p/P4SrrlosMp"><img title="Run code" src="play.png" class="run" /></a>
|
||||
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
|
||||
</pre></div>
|
||||
|
||||
@ -117,7 +117,8 @@ goroutine to respond.</p>
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<div class="highlight"><pre> <span class="kd">var</span> <span class="nx">ops</span> <span class="kt">int64</span> <span class="p">=</span> <span class="mi">0</span>
|
||||
<div class="highlight"><pre> <span class="kd">var</span> <span class="nx">readOps</span> <span class="kt">uint64</span> <span class="p">=</span> <span class="mi">0</span>
|
||||
<span class="kd">var</span> <span class="nx">writeOps</span> <span class="kt">uint64</span> <span class="p">=</span> <span class="mi">0</span>
|
||||
</pre></div>
|
||||
|
||||
</td>
|
||||
@ -190,7 +191,8 @@ result over the provided <code>resp</code> channel.</p>
|
||||
<span class="nx">resp</span><span class="p">:</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">int</span><span class="p">)}</span>
|
||||
<span class="nx">reads</span> <span class="o"><-</span> <span class="nx">read</span>
|
||||
<span class="o"><-</span><span class="nx">read</span><span class="p">.</span><span class="nx">resp</span>
|
||||
<span class="nx">atomic</span><span class="p">.</span><span class="nx">AddInt64</span><span class="p">(</span><span class="o">&</span><span class="nx">ops</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||||
<span class="nx">atomic</span><span class="p">.</span><span class="nx">AddUint64</span><span class="p">(</span><span class="o">&</span><span class="nx">readOps</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||||
<span class="nx">time</span><span class="p">.</span><span class="nx">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Millisecond</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}()</span>
|
||||
<span class="p">}</span>
|
||||
@ -216,7 +218,8 @@ approach.</p>
|
||||
<span class="nx">resp</span><span class="p">:</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">bool</span><span class="p">)}</span>
|
||||
<span class="nx">writes</span> <span class="o"><-</span> <span class="nx">write</span>
|
||||
<span class="o"><-</span><span class="nx">write</span><span class="p">.</span><span class="nx">resp</span>
|
||||
<span class="nx">atomic</span><span class="p">.</span><span class="nx">AddInt64</span><span class="p">(</span><span class="o">&</span><span class="nx">ops</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||||
<span class="nx">atomic</span><span class="p">.</span><span class="nx">AddUint64</span><span class="p">(</span><span class="o">&</span><span class="nx">writeOps</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||||
<span class="nx">time</span><span class="p">.</span><span class="nx">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Millisecond</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}()</span>
|
||||
<span class="p">}</span>
|
||||
@ -240,13 +243,15 @@ approach.</p>
|
||||
|
||||
<tr>
|
||||
<td class="docs">
|
||||
<p>Finally, capture and report the <code>ops</code> count.</p>
|
||||
<p>Finally, capture and report the op counts.</p>
|
||||
|
||||
</td>
|
||||
<td class="code">
|
||||
|
||||
<div class="highlight"><pre> <span class="nx">opsFinal</span> <span class="o">:=</span> <span class="nx">atomic</span><span class="p">.</span><span class="nx">LoadInt64</span><span class="p">(</span><span class="o">&</span><span class="nx">ops</span><span class="p">)</span>
|
||||
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">"ops:"</span><span class="p">,</span> <span class="nx">opsFinal</span><span class="p">)</span>
|
||||
<div class="highlight"><pre> <span class="nx">readOpsFinal</span> <span class="o">:=</span> <span class="nx">atomic</span><span class="p">.</span><span class="nx">LoadUint64</span><span class="p">(</span><span class="o">&</span><span class="nx">readOps</span><span class="p">)</span>
|
||||
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">"readOps:"</span><span class="p">,</span> <span class="nx">readOpsFinal</span><span class="p">)</span>
|
||||
<span class="nx">writeOpsFinal</span> <span class="o">:=</span> <span class="nx">atomic</span><span class="p">.</span><span class="nx">LoadUint64</span><span class="p">(</span><span class="o">&</span><span class="nx">writeOps</span><span class="p">)</span>
|
||||
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">"writeOps:"</span><span class="p">,</span> <span class="nx">writeOpsFinal</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
@ -260,14 +265,15 @@ approach.</p>
|
||||
<tr>
|
||||
<td class="docs">
|
||||
<p>Running our program shows that the goroutine-based
|
||||
state management example achieves about 800,000
|
||||
operations per second.</p>
|
||||
state management example completes about 80,000
|
||||
total operations.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<div class="highlight"><pre><span class="gp">$</span> go run stateful-goroutines.go
|
||||
<span class="go">ops: 807434</span>
|
||||
<span class="go">readOps: 71708</span>
|
||||
<span class="go">writeOps: 7177</span>
|
||||
</pre></div>
|
||||
|
||||
</td>
|
||||
|
Loading…
x
Reference in New Issue
Block a user