Когда у вас есть io.Reader
, наиболее распространенным способом чтения является ioutil.ReadAll
, но это не лучший и самый эффективный способ.
Итак, вот три функции для сравнения различных методов демаршалинга JSON из io.Reader
…
- С
ioutil.ReadAll
func IOUtilReadAll(reader io.Reader) (map[string]interface{}, error) { var ( m map[string]interface{} b, _ = ioutil.ReadAll(reader) ) return m, json.Unmarshal(b, &m) }
2. С io.Copy
func IOCopy(reader io.Reader) (map[string]interface{}, error) { var ( m map[string]interface{} buf bytes.Buffer _, _ = io.Copy(&buf, reader) ) return m, json.Unmarshal(buf.Bytes(), &m) }
3. С json.Decoder
func JsonDecoder(reader io.Reader) (map[string]interface{}, error) { var m map[string]interface{} return m, json.NewDecoder(reader).Decode(&m) }
А теперь давайте посмотрим на них!
var jsonStr = `{"one":"foobar","two":"foobar","three":"foobar","four":"foobar","five":"foobar","six":"foobar","seven":"foobar","eight":"foobar","nine":"foobar","ten":"foobar"}` func BenchmarkJsonDecoder(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { JsonDecoder(strings.NewReader(jsonStr)) } } func BenchmarkIOUtilReadAll(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { IOUtilReadAll(strings.NewReader(jsonStr)) } } func BenchmarkIOCopy(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { IOCopy(strings.NewReader(jsonStr)) } }
Я передаю strings.NewReader
всем трем функциям для согласованности, хотя для json.Decoder
это не обязательно, так как это не истощает io.Reader
.
И вот результаты ...
BenchmarkJsonDecoder BenchmarkJsonDecoder-8 180230 6741 ns/op 2766 B/op 69 allocs/op BenchmarkIOUtilReadAll BenchmarkIOUtilReadAll-8 168019 6928 ns/op 4126 B/op 69 allocs/op BenchmarkIOCopy BenchmarkIOCopy-8 158901 6677 ns/op 2286 B/op 69 allocs/op
Бум! Хотя есть минимальные различия в ns / op, B / op - ошеломляющие 2x!
Но не верьте моим словам. Если вы используете ioutil.ReadAll
, запустите тест и сравните разницу. Это может быть просто небольшое улучшение производительности вашего приложения, и эти усилия лучше потратить на что-то другое.
Надеюсь, это будет полезно. Хлопайте мне (точнее, этой статье), если вы так думаете.
Следуйте за мной, если вы еще этого не сделали!