Skip to content

Commit 7eb7829

Browse files
authoredDec 16, 2024··
fix(fs): fix mergefs bug where files were opened too many times (#2287)
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
1 parent 40c38b7 commit 7eb7829

File tree

3 files changed

+195
-180
lines changed

3 files changed

+195
-180
lines changed
 

‎internal/datafs/mergefs.go

+44-31
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ func (f *mergeFS) Open(name string) (fs.File, error) {
122122
// unescaped '+' characters to make it simpler to provide types like
123123
// "application/array+json"
124124
overrideType := typeOverrideParam()
125-
mimeType := u.Query().Get(overrideType)
126-
mimeType = strings.ReplaceAll(mimeType, " ", "+")
125+
mimeTypeHint := u.Query().Get(overrideType)
126+
mimeTypeHint = strings.ReplaceAll(mimeTypeHint, " ", "+")
127127

128128
// now that we have the hint, remove it from the URL - we can't have it
129129
// leaking into the filesystem layer
@@ -151,23 +151,6 @@ func (f *mergeFS) Open(name string) (fs.File, error) {
151151

152152
fsys = fsimpl.WithHTTPClientFS(f.httpClient, fsys)
153153

154-
// find the content type
155-
fi, err := fs.Stat(fsys, base)
156-
if err != nil {
157-
return nil, &fs.PathError{
158-
Op: "open", Path: name,
159-
Err: fmt.Errorf("stat merge part %q: %w", part, err),
160-
}
161-
}
162-
163-
if fi.ModTime().After(modTime) {
164-
modTime = fi.ModTime()
165-
}
166-
167-
if mimeType == "" {
168-
mimeType = fsimpl.ContentType(fi)
169-
}
170-
171154
f, err := fsys.Open(base)
172155
if err != nil {
173156
return nil, &fs.PathError{
@@ -176,7 +159,7 @@ func (f *mergeFS) Open(name string) (fs.File, error) {
176159
}
177160
}
178161

179-
subFiles[i] = subFile{f, mimeType}
162+
subFiles[i] = subFile{f, mimeTypeHint}
180163
}
181164

182165
return &mergeFile{
@@ -226,18 +209,16 @@ func (f *mergeFile) Read(p []byte) (int, error) {
226209
if f.merged == nil {
227210
f.readMux.Lock()
228211
defer f.readMux.Unlock()
212+
229213
// read from all and merge
230-
data := make([]map[string]interface{}, len(f.subFiles))
214+
data := make([]map[string]any, len(f.subFiles))
231215
for i, sf := range f.subFiles {
232-
b, err := io.ReadAll(sf)
233-
if err != nil && !errors.Is(err, io.EOF) {
234-
return 0, fmt.Errorf("readAll: %w", err)
235-
}
236-
237-
data[i], err = parseMap(sf.contentType, string(b))
216+
d, err := f.readSubFile(sf)
238217
if err != nil {
239-
return 0, fmt.Errorf("parsing map with content type %s: %w", sf.contentType, err)
218+
return 0, fmt.Errorf("readSubFile: %w", err)
240219
}
220+
221+
data[i] = d
241222
}
242223

243224
md, err := mergeData(data)
@@ -253,6 +234,36 @@ func (f *mergeFile) Read(p []byte) (int, error) {
253234
return f.merged.Read(p)
254235
}
255236

237+
func (f *mergeFile) readSubFile(sf subFile) (map[string]any, error) {
238+
// stat for content type and modTime
239+
fi, err := sf.Stat()
240+
if err != nil {
241+
return nil, fmt.Errorf("stat merge part %q: %w", f.name, err)
242+
}
243+
244+
// the merged file's modTime is the most recent of all the sub-files
245+
if fi.ModTime().After(f.modTime) {
246+
f.modTime = fi.ModTime()
247+
}
248+
249+
// if we haven't been given a content type hint, guess the normal way
250+
if sf.contentType == "" {
251+
sf.contentType = fsimpl.ContentType(fi)
252+
}
253+
254+
b, err := io.ReadAll(sf)
255+
if err != nil && !errors.Is(err, io.EOF) {
256+
return nil, fmt.Errorf("readAll: %w", err)
257+
}
258+
259+
sfData, err := parseMap(sf.contentType, string(b))
260+
if err != nil {
261+
return nil, fmt.Errorf("parsing map with content type %s: %w", sf.contentType, err)
262+
}
263+
264+
return sfData, nil
265+
}
266+
256267
func mergeData(data []map[string]interface{}) ([]byte, error) {
257268
dst := data[0]
258269
data = data[1:]
@@ -269,17 +280,19 @@ func mergeData(data []map[string]interface{}) ([]byte, error) {
269280
return []byte(s), nil
270281
}
271282

272-
func parseMap(mimeType, data string) (map[string]interface{}, error) {
283+
func parseMap(mimeType, data string) (map[string]any, error) {
273284
datum, err := parsers.ParseData(mimeType, data)
274285
if err != nil {
275286
return nil, fmt.Errorf("parseData: %w", err)
276287
}
277-
var m map[string]interface{}
288+
289+
var m map[string]any
278290
switch datum := datum.(type) {
279-
case map[string]interface{}:
291+
case map[string]any:
280292
m = datum
281293
default:
282294
return nil, fmt.Errorf("unexpected data type '%T' for datasource (type %s); merge: can only merge maps", datum, mimeType)
283295
}
296+
284297
return m, nil
285298
}

‎internal/datafs/mergefs_test.go

+70-92
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package datafs
22

33
import (
44
"context"
5+
"fmt"
56
"io"
67
"io/fs"
78
"mime"
@@ -31,19 +32,7 @@ func setupMergeFsys(ctx context.Context, t *testing.T) fs.FS {
3132
yamlContent := "hello: earth\ngoodnight: moon\n"
3233
arrayContent := `["hello", "world"]`
3334

34-
wd, _ := os.Getwd()
35-
36-
// MapFS doesn't support windows path separators, so we use / exclusively
37-
// in this test
38-
vol := filepath.VolumeName(wd)
39-
if vol != "" && wd != vol {
40-
wd = wd[len(vol)+1:]
41-
} else if wd[0] == '/' {
42-
wd = wd[1:]
43-
}
44-
wd = filepath.ToSlash(wd)
45-
46-
t.Logf("wd: %s", wd)
35+
wd := wdForTest(t)
4736

4837
fsys := WrapWdFS(fstest.MapFS{
4938
"tmp": {Mode: fs.ModeDir | 0o777},
@@ -90,84 +79,22 @@ func setupMergeFsys(ctx context.Context, t *testing.T) fs.FS {
9079
return fsys
9180
}
9281

93-
// func TestReadMerge(t *testing.T) {
94-
// ctx := context.Background()
95-
96-
// jsonContent := `{"hello": "world"}`
97-
// yamlContent := "hello: earth\ngoodnight: moon\n"
98-
// arrayContent := `["hello", "world"]`
99-
100-
// mergedContent := "goodnight: moon\nhello: world\n"
101-
102-
// fsys := fstest.MapFS{}
103-
// fsys["tmp"] = &fstest.MapFile{Mode: fs.ModeDir | 0777}
104-
// fsys["tmp/jsonfile.json"] = &fstest.MapFile{Data: []byte(jsonContent)}
105-
// fsys["tmp/array.json"] = &fstest.MapFile{Data: []byte(arrayContent)}
106-
// fsys["tmp/yamlfile.yaml"] = &fstest.MapFile{Data: []byte(yamlContent)}
107-
// fsys["tmp/textfile.txt"] = &fstest.MapFile{Data: []byte(`plain text...`)}
108-
109-
// // workding dir with volume name trimmed
110-
// wd, _ := os.Getwd()
111-
// vol := filepath.VolumeName(wd)
112-
// wd = wd[len(vol)+1:]
113-
114-
// fsys[path.Join(wd, "jsonfile.json")] = &fstest.MapFile{Data: []byte(jsonContent)}
115-
// fsys[path.Join(wd, "array.json")] = &fstest.MapFile{Data: []byte(arrayContent)}
116-
// fsys[path.Join(wd, "yamlfile.yaml")] = &fstest.MapFile{Data: []byte(yamlContent)}
117-
// fsys[path.Join(wd, "textfile.txt")] = &fstest.MapFile{Data: []byte(`plain text...`)}
118-
119-
// fsmux := fsimpl.NewMux()
120-
// fsmux.Add(fsimpl.WrappedFSProvider(&fsys, "file"))
121-
// ctx = datafs.ContextWithFSProvider(ctx, fsmux)
122-
123-
// source := &Source{Alias: "foo", URL: mustParseURL("merge:file:///tmp/jsonfile.json|file:///tmp/yamlfile.yaml")}
124-
// d := &Data{
125-
// Sources: map[string]*Source{
126-
// "foo": source,
127-
// "bar": {Alias: "bar", URL: mustParseURL("file:///tmp/jsonfile.json")},
128-
// "baz": {Alias: "baz", URL: mustParseURL("file:///tmp/yamlfile.yaml")},
129-
// "text": {Alias: "text", URL: mustParseURL("file:///tmp/textfile.txt")},
130-
// "badscheme": {Alias: "badscheme", URL: mustParseURL("bad:///scheme.json")},
131-
// "badtype": {Alias: "badtype", URL: mustParseURL("file:///tmp/textfile.txt?type=foo/bar")},
132-
// "array": {Alias: "array", URL: mustParseURL("file:///tmp/array.json?type=" + url.QueryEscape(jsonArrayMimetype))},
133-
// },
134-
// Ctx: ctx,
135-
// }
136-
137-
// actual, err := d.readMerge(ctx, source)
138-
// require.NoError(t, err)
139-
// assert.Equal(t, mergedContent, string(actual))
140-
141-
// source.URL = mustParseURL("merge:bar|baz")
142-
// actual, err = d.readMerge(ctx, source)
143-
// require.NoError(t, err)
144-
// assert.Equal(t, mergedContent, string(actual))
145-
146-
// source.URL = mustParseURL("merge:./jsonfile.json|baz")
147-
// actual, err = d.readMerge(ctx, source)
148-
// require.NoError(t, err)
149-
// assert.Equal(t, mergedContent, string(actual))
150-
151-
// source.URL = mustParseURL("merge:file:///tmp/jsonfile.json")
152-
// _, err = d.readMerge(ctx, source)
153-
// require.Error(t, err)
154-
155-
// source.URL = mustParseURL("merge:bogusalias|file:///tmp/jsonfile.json")
156-
// _, err = d.readMerge(ctx, source)
157-
// require.Error(t, err)
158-
159-
// source.URL = mustParseURL("merge:file:///tmp/jsonfile.json|badscheme")
160-
// _, err = d.readMerge(ctx, source)
161-
// require.Error(t, err)
162-
163-
// source.URL = mustParseURL("merge:file:///tmp/jsonfile.json|badtype")
164-
// _, err = d.readMerge(ctx, source)
165-
// require.Error(t, err)
166-
167-
// source.URL = mustParseURL("merge:file:///tmp/jsonfile.json|array")
168-
// _, err = d.readMerge(ctx, source)
169-
// require.Error(t, err)
170-
// }
82+
func wdForTest(t *testing.T) string {
83+
t.Helper()
84+
85+
wd, _ := os.Getwd()
86+
87+
// MapFS doesn't support windows path separators, so we use / exclusively
88+
vol := filepath.VolumeName(wd)
89+
if vol != "" && wd != vol {
90+
wd = wd[len(vol)+1:]
91+
} else if wd[0] == '/' {
92+
wd = wd[1:]
93+
}
94+
wd = filepath.ToSlash(wd)
95+
96+
return wd
97+
}
17198

17299
func TestMergeData(t *testing.T) {
173100
def := map[string]interface{}{
@@ -228,7 +155,6 @@ func TestMergeData(t *testing.T) {
228155
}
229156

230157
func TestMergeFS_Open(t *testing.T) {
231-
// u, _ := url.Parse("merge:")
232158
fsys := setupMergeFsys(context.Background(), t)
233159
assert.IsType(t, &mergeFS{}, fsys)
234160

@@ -354,3 +280,55 @@ func TestMergeFS_ReadFile(t *testing.T) {
354280
})
355281
}
356282
}
283+
284+
func TestMergeFS_ReadsSubFilesOnce(t *testing.T) {
285+
mergedContent := "goodnight: moon\nhello: world\n"
286+
287+
wd := wdForTest(t)
288+
289+
fsys := WrapWdFS(
290+
openOnce(&fstest.MapFS{
291+
path.Join(wd, "tmp/jsonfile.json"): {Data: []byte(`{"hello": "world"}`)},
292+
path.Join(wd, "tmp/yamlfile.yaml"): {Data: []byte("hello: earth\ngoodnight: moon\n")},
293+
}))
294+
295+
mux := fsimpl.NewMux()
296+
mux.Add(MergeFS)
297+
mux.Add(WrappedFSProvider(fsys, "file", ""))
298+
299+
ctx := ContextWithFSProvider(context.Background(), mux)
300+
301+
reg := NewRegistry()
302+
reg.Register("jsonfile", config.DataSource{URL: mustParseURL("tmp/jsonfile.json")})
303+
reg.Register("yamlfile", config.DataSource{URL: mustParseURL("tmp/yamlfile.yaml")})
304+
305+
fsys, err := NewMergeFS(mustParseURL("merge:///"))
306+
require.NoError(t, err)
307+
308+
fsys = WithDataSourceRegistryFS(reg, fsys)
309+
fsys = fsimpl.WithContextFS(ctx, fsys)
310+
311+
b, err := fs.ReadFile(fsys, "jsonfile|yamlfile")
312+
require.NoError(t, err)
313+
assert.Equal(t, mergedContent, string(b))
314+
}
315+
316+
type openOnceFS struct {
317+
fs *fstest.MapFS
318+
opened map[string]struct{}
319+
}
320+
321+
// a filesystem that only allows opening or stating a file once
322+
func openOnce(fsys *fstest.MapFS) fs.FS {
323+
return &openOnceFS{fs: fsys, opened: map[string]struct{}{}}
324+
}
325+
326+
func (f *openOnceFS) Open(name string) (fs.File, error) {
327+
if _, ok := f.opened[name]; ok {
328+
return nil, fmt.Errorf("open: %q already opened", name)
329+
}
330+
331+
f.opened[name] = struct{}{}
332+
333+
return f.fs.Open(name)
334+
}

‎internal/tests/integration/datasources_merge_test.go

+81-57
Original file line numberDiff line numberDiff line change
@@ -35,62 +35,86 @@ func setupDatasourcesMergeTest(t *testing.T) (*fs.Dir, *httptest.Server) {
3535
func TestDatasources_Merge(t *testing.T) {
3636
tmpDir, srv := setupDatasourcesMergeTest(t)
3737

38-
o, e, err := cmd(t,
39-
"-d", "user="+tmpDir.Join("config.json"),
40-
"-d", "default="+tmpDir.Join("default.yml"),
41-
"-d", "config=merge:user|default",
42-
"-i", `{{ ds "config" | toJSON }}`,
43-
).run()
44-
assertSuccess(t, o, e, err, `{"foo":{"bar":"baz"},"isDefault":false,"isOverride":true,"other":true}`)
45-
46-
o, e, err = cmd(t,
47-
"-d", "default="+tmpDir.Join("default.yml"),
48-
"-d", "config=merge:user|default",
49-
"-i", `{{ defineDatasource "user" `+"`"+tmpDir.Join("config.json")+"`"+` }}{{ ds "config" | toJSON }}`,
50-
).run()
51-
assertSuccess(t, o, e, err, `{"foo":{"bar":"baz"},"isDefault":false,"isOverride":true,"other":true}`)
52-
53-
o, e, err = cmd(t,
54-
"-d", "default="+tmpDir.Join("default.yml"),
55-
"-d", "config=merge:"+srv.URL+"/foo.json|default",
56-
"-i", `{{ ds "config" | toJSON }}`,
57-
).run()
58-
assertSuccess(t, o, e, err, `{"foo":"bar","isDefault":true,"isOverride":false,"other":true}`)
59-
60-
o, e, err = cmd(t,
61-
"-c", "merged=merge:"+srv.URL+"/2.env|"+srv.URL+"/1.env",
62-
"-i", `FOO is {{ .merged.FOO }}`,
63-
).run()
64-
assertSuccess(t, o, e, err, `FOO is 3`)
65-
66-
o, e, err = cmd(t,
67-
"-c", "default="+tmpDir.Join("default.yml"),
68-
"-i", `{{ defineDatasource "merged" "merge:`+srv.URL+`/foo.json|default" -}}
38+
t.Run("from two aliased datasources", func(t *testing.T) {
39+
o, e, err := cmd(t,
40+
"-d", "user="+tmpDir.Join("config.json"),
41+
"-d", "default="+tmpDir.Join("default.yml"),
42+
"-d", "config=merge:user|default",
43+
"-i", `{{ ds "config" | toJSON }}`,
44+
).run()
45+
assertSuccess(t, o, e, err, `{"foo":{"bar":"baz"},"isDefault":false,"isOverride":true,"other":true}`)
46+
})
47+
48+
t.Run("with dynamic datasource", func(t *testing.T) {
49+
o, e, err := cmd(t,
50+
"-d", "default="+tmpDir.Join("default.yml"),
51+
"-d", "config=merge:user|default",
52+
"-i", `{{ defineDatasource "user" `+"`"+tmpDir.Join("config.json")+"`"+` }}{{ ds "config" | toJSON }}`,
53+
).run()
54+
assertSuccess(t, o, e, err, `{"foo":{"bar":"baz"},"isDefault":false,"isOverride":true,"other":true}`)
55+
})
56+
57+
t.Run("with inline datasource", func(t *testing.T) {
58+
o, e, err := cmd(t,
59+
"-d", "default="+tmpDir.Join("default.yml"),
60+
"-d", "config=merge:"+srv.URL+"/foo.json|default",
61+
"-i", `{{ ds "config" | toJSON }}`,
62+
).run()
63+
assertSuccess(t, o, e, err, `{"foo":"bar","isDefault":true,"isOverride":false,"other":true}`)
64+
})
65+
66+
t.Run("with two inline env datasources", func(t *testing.T) {
67+
o, e, err := cmd(t,
68+
"-c", "merged=merge:"+srv.URL+"/2.env|"+srv.URL+"/1.env",
69+
"-i", `FOO is {{ .merged.FOO }}`,
70+
).run()
71+
assertSuccess(t, o, e, err, `FOO is 3`)
72+
})
73+
74+
t.Run("inline merge with inline datasource", func(t *testing.T) {
75+
o, e, err := cmd(t,
76+
"-c", "default="+tmpDir.Join("default.yml"),
77+
"-i", `{{ defineDatasource "merged" "merge:`+srv.URL+`/foo.json|default" -}}
6978
{{ ds "merged" | toJSON }}`,
70-
).run()
71-
assertSuccess(t, o, e, err, `{"foo":"bar","isDefault":true,"isOverride":false,"other":true}`)
72-
73-
o, e, err = cmd(t,
74-
"-d", "default="+tmpDir.Join("default.yml"),
75-
"-d", "wrongtype="+srv.URL+"/wrongtype.txt?type=application/json",
76-
"-d", "config=merge:wrongtype|default",
77-
"-i", `{{ ds "config" | toJSON }}`,
78-
).run()
79-
assertSuccess(t, o, e, err, `{"foo":"bar","isDefault":true,"isOverride":false,"other":true}`)
80-
81-
o, e, err = cmd(t,
82-
"-d", "default="+tmpDir.Join("default.yml"),
83-
"-d", "wrongtype="+srv.URL+"/wrongtype.txt?_=application/json",
84-
"-d", "config=merge:wrongtype|default",
85-
"-i", `{{ ds "config" | toJSON }}`,
86-
).withEnv("GOMPLATE_TYPE_PARAM", "_").run()
87-
assertSuccess(t, o, e, err, `{"foo":"bar","isDefault":true,"isOverride":false,"other":true}`)
88-
89-
o, e, err = cmd(t,
90-
"-c", "default="+tmpDir.Join("default.yml"),
91-
"-c", "params="+srv.URL+"/params?foo=bar&type=http&_type=application/json",
92-
"-c", "merged=merge:params|default",
93-
"-i", `{{ .merged | toJSON }}`,
94-
).withEnv("GOMPLATE_TYPE_PARAM", "_type").run()
95-
assertSuccess(t, o, e, err, `{"foo":["bar"],"isDefault":true,"isOverride":false,"other":true,"type":["http"]}`)
79+
).run()
80+
assertSuccess(t, o, e, err, `{"foo":"bar","isDefault":true,"isOverride":false,"other":true}`)
81+
})
82+
83+
t.Run("with overridden type", func(t *testing.T) {
84+
o, e, err := cmd(t,
85+
"-d", "default="+tmpDir.Join("default.yml"),
86+
"-d", "wrongtype="+srv.URL+"/wrongtype.txt?type=application/json",
87+
"-d", "config=merge:wrongtype|default",
88+
"-i", `{{ ds "config" | toJSON }}`,
89+
).run()
90+
assertSuccess(t, o, e, err, `{"foo":"bar","isDefault":true,"isOverride":false,"other":true}`)
91+
})
92+
93+
t.Run("type overridden by env var", func(t *testing.T) {
94+
o, e, err := cmd(t,
95+
"-d", "default="+tmpDir.Join("default.yml"),
96+
"-d", "wrongtype="+srv.URL+"/wrongtype.txt?_=application/json",
97+
"-d", "config=merge:wrongtype|default",
98+
"-i", `{{ ds "config" | toJSON }}`,
99+
).withEnv("GOMPLATE_TYPE_PARAM", "_").run()
100+
assertSuccess(t, o, e, err, `{"foo":"bar","isDefault":true,"isOverride":false,"other":true}`)
101+
102+
o, e, err = cmd(t,
103+
"-c", "default="+tmpDir.Join("default.yml"),
104+
"-c", "params="+srv.URL+"/params?foo=bar&type=http&_type=application/json",
105+
"-c", "merged=merge:params|default",
106+
"-i", `{{ .merged | toJSON }}`,
107+
).withEnv("GOMPLATE_TYPE_PARAM", "_type").run()
108+
assertSuccess(t, o, e, err, `{"foo":["bar"],"isDefault":true,"isOverride":false,"other":true,"type":["http"]}`)
109+
})
110+
111+
t.Run("from stdin", func(t *testing.T) {
112+
o, e, err := cmd(t,
113+
"-d", "stdindata=stdin:///in.json",
114+
"-d", "filedata="+srv.URL+"/foo.json",
115+
"-d", "merged=merge:stdindata|filedata",
116+
"-i", `{{ ds "merged" | toJSON }}`,
117+
).withStdin(`{"baz": "qux"}`).run()
118+
assertSuccess(t, o, e, err, `{"baz":"qux","foo":"bar"}`)
119+
})
96120
}

1 commit comments

Comments
 (1)

github-actions[bot] commented on Dec 16, 2024

@github-actions[bot]

Benchmark

Benchmark suite Current: 7eb7829 Previous: 66fd58b Ratio
BenchmarkFlatten/depth-1_[]int([1_2_3]) 171.9 ns/op 168 B/op 5 allocs/op 165.7 ns/op 168 B/op 5 allocs/op 1.04
BenchmarkFlatten/depth-1_[]int([1_2_3]) - ns/op 171.9 ns/op 165.7 ns/op 1.04
BenchmarkFlatten/depth-1_[]int([1_2_3]) - B/op 168 B/op 168 B/op 1
BenchmarkFlatten/depth-1_[]int([1_2_3]) - allocs/op 5 allocs/op 5 allocs/op 1
BenchmarkFlatten/depth-1_[3]int([1_2_3]) 127 ns/op 144 B/op 2 allocs/op 117.2 ns/op 144 B/op 2 allocs/op 1.08
BenchmarkFlatten/depth-1_[3]int([1_2_3]) - ns/op 127 ns/op 117.2 ns/op 1.08
BenchmarkFlatten/depth-1_[3]int([1_2_3]) - B/op 144 B/op 144 B/op 1
BenchmarkFlatten/depth-1_[3]int([1_2_3]) - allocs/op 2 allocs/op 2 allocs/op 1
BenchmarkFlatten/depth-1_[]interface_{}([[]_[1_2]_3]) 205.1 ns/op 208 B/op 5 allocs/op 203.4 ns/op 208 B/op 5 allocs/op 1.01
BenchmarkFlatten/depth-1_[]interface_{}([[]_[1_2]_3]) - ns/op 205.1 ns/op 203.4 ns/op 1.01
BenchmarkFlatten/depth-1_[]interface_{}([[]_[1_2]_3]) - B/op 208 B/op 208 B/op 1
BenchmarkFlatten/depth-1_[]interface_{}([[]_[1_2]_3]) - allocs/op 5 allocs/op 5 allocs/op 1
BenchmarkFlatten/depth-1_[]interface_{}([[one]_[[1_2]]_3]) 437 ns/op 344 B/op 11 allocs/op 422.8 ns/op 344 B/op 11 allocs/op 1.03
BenchmarkFlatten/depth-1_[]interface_{}([[one]_[[1_2]]_3]) - ns/op 437 ns/op 422.8 ns/op 1.03
BenchmarkFlatten/depth-1_[]interface_{}([[one]_[[1_2]]_3]) - B/op 344 B/op 344 B/op 1
BenchmarkFlatten/depth-1_[]interface_{}([[one]_[[1_2]]_3]) - allocs/op 11 allocs/op 11 allocs/op 1
BenchmarkFlatten/depth-1_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) 883.8 ns/op 896 B/op 19 allocs/op 791.2 ns/op 896 B/op 19 allocs/op 1.12
BenchmarkFlatten/depth-1_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) - ns/op 883.8 ns/op 791.2 ns/op 1.12
BenchmarkFlatten/depth-1_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) - B/op 896 B/op 896 B/op 1
BenchmarkFlatten/depth-1_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) - allocs/op 19 allocs/op 19 allocs/op 1
BenchmarkFlatten/depth0_[]int([1_2_3]) 118.2 ns/op 72 B/op 4 allocs/op 114.2 ns/op 72 B/op 4 allocs/op 1.04
BenchmarkFlatten/depth0_[]int([1_2_3]) - ns/op 118.2 ns/op 114.2 ns/op 1.04
BenchmarkFlatten/depth0_[]int([1_2_3]) - B/op 72 B/op 72 B/op 1
BenchmarkFlatten/depth0_[]int([1_2_3]) - allocs/op 4 allocs/op 4 allocs/op 1
BenchmarkFlatten/depth0_[3]int([1_2_3]) 63.67 ns/op 48 B/op 1 allocs/op 63.74 ns/op 48 B/op 1 allocs/op 1.00
BenchmarkFlatten/depth0_[3]int([1_2_3]) - ns/op 63.67 ns/op 63.74 ns/op 1.00
BenchmarkFlatten/depth0_[3]int([1_2_3]) - B/op 48 B/op 48 B/op 1
BenchmarkFlatten/depth0_[3]int([1_2_3]) - allocs/op 1 allocs/op 1 allocs/op 1
BenchmarkFlatten/depth0_[]interface_{}([[]_[1_2]_3]) 4.335 ns/op 0 B/op 0 allocs/op 4.33 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkFlatten/depth0_[]interface_{}([[]_[1_2]_3]) - ns/op 4.335 ns/op 4.33 ns/op 1.00
BenchmarkFlatten/depth0_[]interface_{}([[]_[1_2]_3]) - B/op 0 B/op 0 B/op 1
BenchmarkFlatten/depth0_[]interface_{}([[]_[1_2]_3]) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkFlatten/depth0_[]interface_{}([[one]_[[1_2]]_3]) 4.333 ns/op 0 B/op 0 allocs/op 4.442 ns/op 0 B/op 0 allocs/op 0.98
BenchmarkFlatten/depth0_[]interface_{}([[one]_[[1_2]]_3]) - ns/op 4.333 ns/op 4.442 ns/op 0.98
BenchmarkFlatten/depth0_[]interface_{}([[one]_[[1_2]]_3]) - B/op 0 B/op 0 B/op 1
BenchmarkFlatten/depth0_[]interface_{}([[one]_[[1_2]]_3]) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkFlatten/depth0_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) 4.334 ns/op 0 B/op 0 allocs/op 4.301 ns/op 0 B/op 0 allocs/op 1.01
BenchmarkFlatten/depth0_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) - ns/op 4.334 ns/op 4.301 ns/op 1.01
BenchmarkFlatten/depth0_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) - B/op 0 B/op 0 B/op 1
BenchmarkFlatten/depth0_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkFlatten/depth1_[]int([1_2_3]) 170.9 ns/op 168 B/op 5 allocs/op 166.1 ns/op 168 B/op 5 allocs/op 1.03
BenchmarkFlatten/depth1_[]int([1_2_3]) - ns/op 170.9 ns/op 166.1 ns/op 1.03
BenchmarkFlatten/depth1_[]int([1_2_3]) - B/op 168 B/op 168 B/op 1
BenchmarkFlatten/depth1_[]int([1_2_3]) - allocs/op 5 allocs/op 5 allocs/op 1
BenchmarkFlatten/depth1_[3]int([1_2_3]) 116.9 ns/op 144 B/op 2 allocs/op 116.9 ns/op 144 B/op 2 allocs/op 1
BenchmarkFlatten/depth1_[3]int([1_2_3]) - ns/op 116.9 ns/op 116.9 ns/op 1
BenchmarkFlatten/depth1_[3]int([1_2_3]) - B/op 144 B/op 144 B/op 1
BenchmarkFlatten/depth1_[3]int([1_2_3]) - allocs/op 2 allocs/op 2 allocs/op 1
BenchmarkFlatten/depth1_[]interface_{}([[]_[1_2]_3]) 160.3 ns/op 144 B/op 4 allocs/op 157.9 ns/op 144 B/op 4 allocs/op 1.02
BenchmarkFlatten/depth1_[]interface_{}([[]_[1_2]_3]) - ns/op 160.3 ns/op 157.9 ns/op 1.02
BenchmarkFlatten/depth1_[]interface_{}([[]_[1_2]_3]) - B/op 144 B/op 144 B/op 1
BenchmarkFlatten/depth1_[]interface_{}([[]_[1_2]_3]) - allocs/op 4 allocs/op 4 allocs/op 1
BenchmarkFlatten/depth1_[]interface_{}([[one]_[[1_2]]_3]) 219.6 ns/op 168 B/op 5 allocs/op 210.8 ns/op 168 B/op 5 allocs/op 1.04
BenchmarkFlatten/depth1_[]interface_{}([[one]_[[1_2]]_3]) - ns/op 219.6 ns/op 210.8 ns/op 1.04
BenchmarkFlatten/depth1_[]interface_{}([[one]_[[1_2]]_3]) - B/op 168 B/op 168 B/op 1
BenchmarkFlatten/depth1_[]interface_{}([[one]_[[1_2]]_3]) - allocs/op 5 allocs/op 5 allocs/op 1
BenchmarkFlatten/depth1_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) 145 ns/op 128 B/op 3 allocs/op 140.6 ns/op 128 B/op 3 allocs/op 1.03
BenchmarkFlatten/depth1_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) - ns/op 145 ns/op 140.6 ns/op 1.03
BenchmarkFlatten/depth1_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) - B/op 128 B/op 128 B/op 1
BenchmarkFlatten/depth1_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) - allocs/op 3 allocs/op 3 allocs/op 1
BenchmarkFlatten/depth2_[]int([1_2_3]) 171.9 ns/op 168 B/op 5 allocs/op 166.3 ns/op 168 B/op 5 allocs/op 1.03
BenchmarkFlatten/depth2_[]int([1_2_3]) - ns/op 171.9 ns/op 166.3 ns/op 1.03
BenchmarkFlatten/depth2_[]int([1_2_3]) - B/op 168 B/op 168 B/op 1
BenchmarkFlatten/depth2_[]int([1_2_3]) - allocs/op 5 allocs/op 5 allocs/op 1
BenchmarkFlatten/depth2_[3]int([1_2_3]) 116.6 ns/op 144 B/op 2 allocs/op 116.9 ns/op 144 B/op 2 allocs/op 1.00
BenchmarkFlatten/depth2_[3]int([1_2_3]) - ns/op 116.6 ns/op 116.9 ns/op 1.00
BenchmarkFlatten/depth2_[3]int([1_2_3]) - B/op 144 B/op 144 B/op 1
BenchmarkFlatten/depth2_[3]int([1_2_3]) - allocs/op 2 allocs/op 2 allocs/op 1
BenchmarkFlatten/depth2_[]interface_{}([[]_[1_2]_3]) 205 ns/op 208 B/op 5 allocs/op 203.9 ns/op 208 B/op 5 allocs/op 1.01
BenchmarkFlatten/depth2_[]interface_{}([[]_[1_2]_3]) - ns/op 205 ns/op 203.9 ns/op 1.01
BenchmarkFlatten/depth2_[]interface_{}([[]_[1_2]_3]) - B/op 208 B/op 208 B/op 1
BenchmarkFlatten/depth2_[]interface_{}([[]_[1_2]_3]) - allocs/op 5 allocs/op 5 allocs/op 1
BenchmarkFlatten/depth2_[]interface_{}([[one]_[[1_2]]_3]) 381.1 ns/op 280 B/op 10 allocs/op 368.6 ns/op 280 B/op 10 allocs/op 1.03
BenchmarkFlatten/depth2_[]interface_{}([[one]_[[1_2]]_3]) - ns/op 381.1 ns/op 368.6 ns/op 1.03
BenchmarkFlatten/depth2_[]interface_{}([[one]_[[1_2]]_3]) - B/op 280 B/op 280 B/op 1
BenchmarkFlatten/depth2_[]interface_{}([[one]_[[1_2]]_3]) - allocs/op 10 allocs/op 10 allocs/op 1
BenchmarkFlatten/depth2_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) 323.1 ns/op 272 B/op 8 allocs/op 324.6 ns/op 272 B/op 8 allocs/op 1.00
BenchmarkFlatten/depth2_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) - ns/op 323.1 ns/op 324.6 ns/op 1.00
BenchmarkFlatten/depth2_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) - B/op 272 B/op 272 B/op 1
BenchmarkFlatten/depth2_[]interface_{}([[one]_[[[1]_[2_[3]]]_[4_5]]_6]) - allocs/op 8 allocs/op 8 allocs/op 1
BenchmarkInterfaceSlice/[]int([1_2_3]) 118.2 ns/op 72 B/op 4 allocs/op 112.6 ns/op 72 B/op 4 allocs/op 1.05
BenchmarkInterfaceSlice/[]int([1_2_3]) - ns/op 118.2 ns/op 112.6 ns/op 1.05
BenchmarkInterfaceSlice/[]int([1_2_3]) - B/op 72 B/op 72 B/op 1
BenchmarkInterfaceSlice/[]int([1_2_3]) - allocs/op 4 allocs/op 4 allocs/op 1
BenchmarkInterfaceSlice/[3]int([1_2_3]) 63.8 ns/op 48 B/op 1 allocs/op 60.15 ns/op 48 B/op 1 allocs/op 1.06
BenchmarkInterfaceSlice/[3]int([1_2_3]) - ns/op 63.8 ns/op 60.15 ns/op 1.06
BenchmarkInterfaceSlice/[3]int([1_2_3]) - B/op 48 B/op 48 B/op 1
BenchmarkInterfaceSlice/[3]int([1_2_3]) - allocs/op 1 allocs/op 1 allocs/op 1
BenchmarkInterfaceSlice/[]string([foo_bar_baz_foo_bar_baz_foo_bar_baz_foo_bar_baz]) 573.1 ns/op 384 B/op 13 allocs/op 536.3 ns/op 384 B/op 13 allocs/op 1.07
BenchmarkInterfaceSlice/[]string([foo_bar_baz_foo_bar_baz_foo_bar_baz_foo_bar_baz]) - ns/op 573.1 ns/op 536.3 ns/op 1.07
BenchmarkInterfaceSlice/[]string([foo_bar_baz_foo_bar_baz_foo_bar_baz_foo_bar_baz]) - B/op 384 B/op 384 B/op 1
BenchmarkInterfaceSlice/[]string([foo_bar_baz_foo_bar_baz_foo_bar_baz_foo_bar_baz]) - allocs/op 13 allocs/op 13 allocs/op 1
BenchmarkInterfaceSlice/[12]string([foo_bar_baz_foo_bar_baz_foo_bar_baz_foo_bar_baz]) 161.5 ns/op 192 B/op 1 allocs/op 152.9 ns/op 192 B/op 1 allocs/op 1.06
BenchmarkInterfaceSlice/[12]string([foo_bar_baz_foo_bar_baz_foo_bar_baz_foo_bar_baz]) - ns/op 161.5 ns/op 152.9 ns/op 1.06
BenchmarkInterfaceSlice/[12]string([foo_bar_baz_foo_bar_baz_foo_bar_baz_foo_bar_baz]) - B/op 192 B/op 192 B/op 1
BenchmarkInterfaceSlice/[12]string([foo_bar_baz_foo_bar_baz_foo_bar_baz_foo_bar_baz]) - allocs/op 1 allocs/op 1 allocs/op 1
BenchmarkInterfaceSlice/[]interface_{}([[]_[1_2]_3]) 2.169 ns/op 0 B/op 0 allocs/op 2.202 ns/op 0 B/op 0 allocs/op 0.99
BenchmarkInterfaceSlice/[]interface_{}([[]_[1_2]_3]) - ns/op 2.169 ns/op 2.202 ns/op 0.99
BenchmarkInterfaceSlice/[]interface_{}([[]_[1_2]_3]) - B/op 0 B/op 0 B/op 1
BenchmarkInterfaceSlice/[]interface_{}([[]_[1_2]_3]) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkInterfaceSlice/[3]interface_{}([[]_[1_2]_3]) 69.64 ns/op 48 B/op 1 allocs/op 63.17 ns/op 48 B/op 1 allocs/op 1.10
BenchmarkInterfaceSlice/[3]interface_{}([[]_[1_2]_3]) - ns/op 69.64 ns/op 63.17 ns/op 1.10
BenchmarkInterfaceSlice/[3]interface_{}([[]_[1_2]_3]) - B/op 48 B/op 48 B/op 1
BenchmarkInterfaceSlice/[3]interface_{}([[]_[1_2]_3]) - allocs/op 1 allocs/op 1 allocs/op 1
BenchmarkToBytes 1035 ns/op 40 B/op 3 allocs/op 1125 ns/op 40 B/op 3 allocs/op 0.92
BenchmarkToBytes - ns/op 1035 ns/op 1125 ns/op 0.92
BenchmarkToBytes - B/op 40 B/op 40 B/op 1
BenchmarkToBytes - allocs/op 3 allocs/op 3 allocs/op 1
BenchmarkIsFloat/int(0) 3.1 ns/op 0 B/op 0 allocs/op 3.178 ns/op 0 B/op 0 allocs/op 0.98
BenchmarkIsFloat/int(0) - ns/op 3.1 ns/op 3.178 ns/op 0.98
BenchmarkIsFloat/int(0) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/int(0) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/int(1) 3.272 ns/op 0 B/op 0 allocs/op 3.102 ns/op 0 B/op 0 allocs/op 1.05
BenchmarkIsFloat/int(1) - ns/op 3.272 ns/op 3.102 ns/op 1.05
BenchmarkIsFloat/int(1) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/int(1) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/int(-1) 3.112 ns/op 0 B/op 0 allocs/op 3.135 ns/op 0 B/op 0 allocs/op 0.99
BenchmarkIsFloat/int(-1) - ns/op 3.112 ns/op 3.135 ns/op 0.99
BenchmarkIsFloat/int(-1) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/int(-1) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/uint(42) 3.096 ns/op 0 B/op 0 allocs/op 3.097 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkIsFloat/uint(42) - ns/op 3.096 ns/op 3.097 ns/op 1.00
BenchmarkIsFloat/uint(42) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/uint(42) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/uint8(255) 3.165 ns/op 0 B/op 0 allocs/op 3.097 ns/op 0 B/op 0 allocs/op 1.02
BenchmarkIsFloat/uint8(255) - ns/op 3.165 ns/op 3.097 ns/op 1.02
BenchmarkIsFloat/uint8(255) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/uint8(255) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/uint16(42) 3.096 ns/op 0 B/op 0 allocs/op 3.102 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkIsFloat/uint16(42) - ns/op 3.096 ns/op 3.102 ns/op 1.00
BenchmarkIsFloat/uint16(42) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/uint16(42) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/uint32(42) 3.12 ns/op 0 B/op 0 allocs/op 3.096 ns/op 0 B/op 0 allocs/op 1.01
BenchmarkIsFloat/uint32(42) - ns/op 3.12 ns/op 3.096 ns/op 1.01
BenchmarkIsFloat/uint32(42) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/uint32(42) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/uint64(42) 3.096 ns/op 0 B/op 0 allocs/op 3.101 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkIsFloat/uint64(42) - ns/op 3.096 ns/op 3.101 ns/op 1.00
BenchmarkIsFloat/uint64(42) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/uint64(42) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/int(42) 3.098 ns/op 0 B/op 0 allocs/op 3.101 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkIsFloat/int(42) - ns/op 3.098 ns/op 3.101 ns/op 1.00
BenchmarkIsFloat/int(42) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/int(42) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/int8(127) 3.097 ns/op 0 B/op 0 allocs/op 3.096 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkIsFloat/int8(127) - ns/op 3.097 ns/op 3.096 ns/op 1.00
BenchmarkIsFloat/int8(127) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/int8(127) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/int16(42) 3.096 ns/op 0 B/op 0 allocs/op 3.102 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkIsFloat/int16(42) - ns/op 3.096 ns/op 3.102 ns/op 1.00
BenchmarkIsFloat/int16(42) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/int16(42) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/int32(42) 3.098 ns/op 0 B/op 0 allocs/op 3.094 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkIsFloat/int32(42) - ns/op 3.098 ns/op 3.094 ns/op 1.00
BenchmarkIsFloat/int32(42) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/int32(42) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/int64(42) 3.095 ns/op 0 B/op 0 allocs/op 3.1 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkIsFloat/int64(42) - ns/op 3.095 ns/op 3.1 ns/op 1.00
BenchmarkIsFloat/int64(42) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/int64(42) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/float32(18.3) 2.785 ns/op 0 B/op 0 allocs/op 2.786 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkIsFloat/float32(18.3) - ns/op 2.785 ns/op 2.786 ns/op 1.00
BenchmarkIsFloat/float32(18.3) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/float32(18.3) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/float64(18.3) 2.79 ns/op 0 B/op 0 allocs/op 2.792 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkIsFloat/float64(18.3) - ns/op 2.79 ns/op 2.792 ns/op 1.00
BenchmarkIsFloat/float64(18.3) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/float64(18.3) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/float64(1.5) 2.792 ns/op 0 B/op 0 allocs/op 2.786 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkIsFloat/float64(1.5) - ns/op 2.792 ns/op 2.786 ns/op 1.00
BenchmarkIsFloat/float64(1.5) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/float64(1.5) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/float64(-18.6) 2.794 ns/op 0 B/op 0 allocs/op 2.789 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkIsFloat/float64(-18.6) - ns/op 2.794 ns/op 2.789 ns/op 1.00
BenchmarkIsFloat/float64(-18.6) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/float64(-18.6) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/string(42) 34.74 ns/op 0 B/op 0 allocs/op 34.1 ns/op 0 B/op 0 allocs/op 1.02
BenchmarkIsFloat/string(42) - ns/op 34.74 ns/op 34.1 ns/op 1.02
BenchmarkIsFloat/string(42) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/string(42) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/string(052) 38.45 ns/op 0 B/op 0 allocs/op 38.08 ns/op 0 B/op 0 allocs/op 1.01
BenchmarkIsFloat/string(052) - ns/op 38.45 ns/op 38.08 ns/op 1.01
BenchmarkIsFloat/string(052) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/string(052) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/string(0xff) 74.06 ns/op 52 B/op 2 allocs/op 72.28 ns/op 52 B/op 2 allocs/op 1.02
BenchmarkIsFloat/string(0xff) - ns/op 74.06 ns/op 72.28 ns/op 1.02
BenchmarkIsFloat/string(0xff) - B/op 52 B/op 52 B/op 1
BenchmarkIsFloat/string(0xff) - allocs/op 2 allocs/op 2 allocs/op 1
BenchmarkIsFloat/string(-42) 36.88 ns/op 0 B/op 0 allocs/op 35.95 ns/op 0 B/op 0 allocs/op 1.03
BenchmarkIsFloat/string(-42) - ns/op 36.88 ns/op 35.95 ns/op 1.03
BenchmarkIsFloat/string(-42) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/string(-42) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/string(-0) 32.28 ns/op 0 B/op 0 allocs/op 32.63 ns/op 0 B/op 0 allocs/op 0.99
BenchmarkIsFloat/string(-0) - ns/op 32.28 ns/op 32.63 ns/op 0.99
BenchmarkIsFloat/string(-0) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/string(-0) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkIsFloat/string(3.14) 106.7 ns/op 56 B/op 3 allocs/op 105.3 ns/op 56 B/op 3 allocs/op 1.01
BenchmarkIsFloat/string(3.14) - ns/op 106.7 ns/op 105.3 ns/op 1.01
BenchmarkIsFloat/string(3.14) - B/op 56 B/op 56 B/op 1
BenchmarkIsFloat/string(3.14) - allocs/op 3 allocs/op 3 allocs/op 1
BenchmarkIsFloat/string(-3.14) 121.9 ns/op 64 B/op 3 allocs/op 112.2 ns/op 64 B/op 3 allocs/op 1.09
BenchmarkIsFloat/string(-3.14) - ns/op 121.9 ns/op 112.2 ns/op 1.09
BenchmarkIsFloat/string(-3.14) - B/op 64 B/op 64 B/op 1
BenchmarkIsFloat/string(-3.14) - allocs/op 3 allocs/op 3 allocs/op 1
BenchmarkIsFloat/string(0.00) 104.8 ns/op 56 B/op 3 allocs/op 105.8 ns/op 56 B/op 3 allocs/op 0.99
BenchmarkIsFloat/string(0.00) - ns/op 104.8 ns/op 105.8 ns/op 0.99
BenchmarkIsFloat/string(0.00) - B/op 56 B/op 56 B/op 1
BenchmarkIsFloat/string(0.00) - allocs/op 3 allocs/op 3 allocs/op 1
BenchmarkIsFloat/string(NaN) 94.62 ns/op 54 B/op 3 allocs/op 93.86 ns/op 54 B/op 3 allocs/op 1.01
BenchmarkIsFloat/string(NaN) - ns/op 94.62 ns/op 93.86 ns/op 1.01
BenchmarkIsFloat/string(NaN) - B/op 54 B/op 54 B/op 1
BenchmarkIsFloat/string(NaN) - allocs/op 3 allocs/op 3 allocs/op 1
BenchmarkIsFloat/string(-Inf) 97.06 ns/op 56 B/op 3 allocs/op 92.49 ns/op 56 B/op 3 allocs/op 1.05
BenchmarkIsFloat/string(-Inf) - ns/op 97.06 ns/op 92.49 ns/op 1.05
BenchmarkIsFloat/string(-Inf) - B/op 56 B/op 56 B/op 1
BenchmarkIsFloat/string(-Inf) - allocs/op 3 allocs/op 3 allocs/op 1
BenchmarkIsFloat/string(+Inf) 96.8 ns/op 56 B/op 3 allocs/op 93.17 ns/op 56 B/op 3 allocs/op 1.04
BenchmarkIsFloat/string(+Inf) - ns/op 96.8 ns/op 93.17 ns/op 1.04
BenchmarkIsFloat/string(+Inf) - B/op 56 B/op 56 B/op 1
BenchmarkIsFloat/string(+Inf) - allocs/op 3 allocs/op 3 allocs/op 1
BenchmarkIsFloat/string() 50.73 ns/op 48 B/op 1 allocs/op 49.84 ns/op 48 B/op 1 allocs/op 1.02
BenchmarkIsFloat/string() - ns/op 50.73 ns/op 49.84 ns/op 1.02
BenchmarkIsFloat/string() - B/op 48 B/op 48 B/op 1
BenchmarkIsFloat/string() - allocs/op 1 allocs/op 1 allocs/op 1
BenchmarkIsFloat/string(foo) 72.12 ns/op 51 B/op 2 allocs/op 69.53 ns/op 51 B/op 2 allocs/op 1.04
BenchmarkIsFloat/string(foo) - ns/op 72.12 ns/op 69.53 ns/op 1.04
BenchmarkIsFloat/string(foo) - B/op 51 B/op 51 B/op 1
BenchmarkIsFloat/string(foo) - allocs/op 2 allocs/op 2 allocs/op 1
BenchmarkIsFloat/bool(true) 3.099 ns/op 0 B/op 0 allocs/op 3.097 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkIsFloat/bool(true) - ns/op 3.099 ns/op 3.097 ns/op 1.00
BenchmarkIsFloat/bool(true) - B/op 0 B/op 0 B/op 1
BenchmarkIsFloat/bool(true) - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkLookupIPs 48468 ns/op 1872 B/op 46 allocs/op 50737 ns/op 1840 B/op 44 allocs/op 0.96
BenchmarkLookupIPs - ns/op 48468 ns/op 50737 ns/op 0.96
BenchmarkLookupIPs - B/op 1872 B/op 1840 B/op 1.02
BenchmarkLookupIPs - allocs/op 46 allocs/op 44 allocs/op 1.05
BenchmarkIndent 1837 ns/op 2040 B/op 18 allocs/op 1946 ns/op 2064 B/op 20 allocs/op 0.94
BenchmarkIndent - ns/op 1837 ns/op 1946 ns/op 0.94
BenchmarkIndent - B/op 2040 B/op 2064 B/op 0.99
BenchmarkIndent - allocs/op 18 allocs/op 20 allocs/op 0.90

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.