Optimize Point.NewPointFromBytes

There was a check to ensure that fields exists when unmarshalBinary
is called.  This created a map and other garbage just to see if any
fields exist.

This changes it to use a FieldIterator that does not allocate as
much as the other method.
pull/8269/head
Jason Wilder 2017-04-06 12:46:09 -06:00
parent 03338c69b5
commit c3e0748bd9
2 changed files with 51 additions and 4 deletions

View File

@ -1258,13 +1258,41 @@ func NewPointFromBytes(b []byte) (Point, error) {
if err := p.UnmarshalBinary(b); err != nil {
return nil, err
}
fields, err := p.Fields()
if err != nil {
return nil, err
// This does some basic validation to ensure there are fields and they
// can be unmarshalled as well.
iter := p.FieldIterator()
var hasField bool
for iter.Next() {
if len(iter.FieldKey()) == 0 {
continue
}
hasField = true
switch iter.Type() {
case Float:
_, err := iter.FloatValue()
if err != nil {
return nil, fmt.Errorf("unable to unmarshal field %s: %s", string(iter.FieldKey()), err)
}
case Integer:
_, err := iter.IntegerValue()
if err != nil {
return nil, fmt.Errorf("unable to unmarshal field %s: %s", string(iter.FieldKey()), err)
}
case String:
// Skip since this won't return an error
case Boolean:
_, err := iter.BooleanValue()
if err != nil {
return nil, fmt.Errorf("unable to unmarshal field %s: %s", string(iter.FieldKey()), err)
}
}
}
if len(fields) == 0 {
if !hasField {
return nil, ErrPointMustHaveAField
}
return p, nil
}

View File

@ -131,6 +131,25 @@ func BenchmarkNewPoint(b *testing.B) {
}
}
func BenchmarkNewPointFromBinary(b *testing.B) {
pts, err := models.ParsePointsString("cpu value1=1.0,value2=1.0,value3=3.0,value4=4,value5=\"five\" 1000000000")
if err != nil {
b.Fatalf("unexpected error ParsePointsString: %v", err)
}
bytes, err := pts[0].MarshalBinary()
if err != nil {
b.Fatalf("unexpected error MarshalBinary: %v", err)
}
for i := 0; i < b.N; i++ {
_, err := models.NewPointFromBytes(bytes)
if err != nil {
b.Fatalf("unexpected error NewPointsFromBytes: %v", err)
}
}
}
func BenchmarkParsePointNoTags5000(b *testing.B) {
var batch [5000]string
for i := 0; i < len(batch); i++ {