}
}
-func TestAppendFloatDoesntAllocate(t *testing.T) {
- n := numAllocations(func() {
- var buf [64]byte
- AppendFloat(buf[:0], 1.23, 'g', 5, 64)
- })
- want := 1 // TODO(bradfitz): this might be 0, once escape analysis is better
- if n != want {
- t.Errorf("with local buffer, did %d allocations, want %d", n, want)
- }
- n = numAllocations(func() {
- AppendFloat(globalBuf[:0], 1.23, 'g', 5, 64)
- })
- if n != 0 {
- t.Errorf("with reused buffer, did %d allocations, want 0", n)
- }
-}
-
func BenchmarkFormatFloatDecimal(b *testing.B) {
for i := 0; i < b.N; i++ {
FormatFloat(33909, 'g', -1, 64)
package strconv_test
import (
- "runtime"
. "strconv"
"testing"
)
}
}
-func numAllocations(f func()) int {
- runtime.GC()
- memstats := new(runtime.MemStats)
- runtime.ReadMemStats(memstats)
- n0 := memstats.Mallocs
- f()
- runtime.ReadMemStats(memstats)
- return int(memstats.Mallocs - n0)
-}
-
-var globalBuf [64]byte
-
-func TestAppendUintDoesntAllocate(t *testing.T) {
- n := numAllocations(func() {
- var buf [64]byte
- AppendInt(buf[:0], 123, 10)
- })
- want := 1 // TODO(bradfitz): this might be 0, once escape analysis is better
- if n != want {
- t.Errorf("with local buffer, did %d allocations, want %d", n, want)
- }
- n = numAllocations(func() {
- AppendInt(globalBuf[:0], 123, 10)
- })
- if n != 0 {
- t.Errorf("with reused buffer, did %d allocations, want 0", n)
- }
-}
-
func BenchmarkFormatInt(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, test := range itob64tests {
--- /dev/null
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strconv_test
+
+import (
+ "runtime"
+ . "strconv"
+ "testing"
+)
+
+var (
+ globalBuf [64]byte
+
+ mallocTest = []struct {
+ count int
+ desc string
+ fn func()
+ }{
+ // TODO(bradfitz): this might be 0, once escape analysis is better
+ {1, `AppendInt(localBuf[:0], 123, 10)`, func() {
+ var localBuf [64]byte
+ AppendInt(localBuf[:0], 123, 10)
+ }},
+ {0, `AppendInt(globalBuf[:0], 123, 10)`, func() { AppendInt(globalBuf[:0], 123, 10) }},
+ // TODO(bradfitz): this might be 0, once escape analysis is better
+ {1, `AppendFloat(localBuf[:0], 1.23, 'g', 5, 64)`, func() {
+ var localBuf [64]byte
+ AppendFloat(localBuf[:0], 1.23, 'g', 5, 64)
+ }},
+ {0, `AppendFloat(globalBuf[:0], 1.23, 'g', 5, 64)`, func() { AppendFloat(globalBuf[:0], 1.23, 'g', 5, 64) }},
+ }
+)
+
+func TestCountMallocs(t *testing.T) {
+ for _, mt := range mallocTest {
+ const N = 100
+ memstats := new(runtime.MemStats)
+ runtime.ReadMemStats(memstats)
+ mallocs := 0 - memstats.Mallocs
+ for i := 0; i < N; i++ {
+ mt.fn()
+ }
+ runtime.ReadMemStats(memstats)
+ mallocs += memstats.Mallocs
+ if mallocs/N > uint64(mt.count) {
+ t.Errorf("%s: expected %d mallocs, got %d", mt.desc, mt.count, mallocs/N)
+ }
+ }
+}