<p dir="auto">The <code class="notranslate">encoding/binary</code> package performs more slowly writing <code class="notranslate">uint{8,16,32,64}</code> data vs the corresponding <code class="notranslate">int{8,16,32,64}</code> data. The performance when writing <code class="notranslate">*uints</code> and <code class="notranslate">*ints</code> is almost identical.</p>
<p dir="auto">See <code class="notranslate">binary1.go</code> in <a href="http://play.golang.org/p/--qpN-sy6o" rel="nofollow">http://play.golang.org/p/--qpN-sy6o</a> and <code class="notranslate">binary1_test.go</code> in <a href="http://play.golang.org/p/ypH8OTtYYx" rel="nofollow">http://play.golang.org/p/ypH8OTtYYx</a></p>
<p dir="auto">Here is part of the output from running the benchmark test.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&gt;go test binary1.go binary1_test.go -bench=.
testing: warning: no tests to run
PASS
BenchmarkWrite_int8        10000            171109 ns/op
BenchmarkWrite_uint8        5000            367821 ns/op
BenchmarkWrite_int8_p      10000            114706 ns/op
BenchmarkWrite_uint8_p     10000            115306 ns/op"><pre class="notranslate"><code class="notranslate">&gt;go test binary1.go binary1_test.go -bench=.
testing: warning: no tests to run
PASS
BenchmarkWrite_int8        10000            171109 ns/op
BenchmarkWrite_uint8        5000            367821 ns/op
BenchmarkWrite_int8_p      10000            114706 ns/op
BenchmarkWrite_uint8_p     10000            115306 ns/op
</code></pre></div>
<p dir="auto">The results for larger integers are similar.</p>
<p dir="auto">The problem appears to be in the <code class="notranslate">encoding/binary</code> package's <code class="notranslate">intDataSize</code> function:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="// intDataSize returns the size of the data required to represent the data when encoded.
// It returns zero if the type cannot be implemented by the fast path in Read or Write.
func intDataSize(data interface{}) int {
    switch data := data.(type) {
    case int8, *int8, *uint8:
        return 1
    case []int8:
        return len(data)
    case []uint8:
        return len(data)"><pre class="notranslate"><code class="notranslate">// intDataSize returns the size of the data required to represent the data when encoded.
// It returns zero if the type cannot be implemented by the fast path in Read or Write.
func intDataSize(data interface{}) int {
    switch data := data.(type) {
    case int8, *int8, *uint8:
        return 1
    case []int8:
        return len(data)
    case []uint8:
        return len(data)
</code></pre></div>
<p dir="auto">The first case of the switch does not include <code class="notranslate">uint8</code> so the fast path is not used. The data size is looked up later using reflection instead of using this hard coded size. Larger unsigned ints are also missing later in the switch.</p>
<pre class="notranslate">The reflect slow path showed up in pprof for a uint64 data type:
<a href="https://code.google.com/r/cafxx-golang/source/detail?r=20d0244f15dc2584b540c90437f70ce7ab840219" rel="nofollow">https://code.google.com/r/cafxx-golang/source/detail?r=20d0244f15dc2584b540c90437f70ce7ab840219</a></pre>