allocation & perf improvements
This commit is contained in:
		
							parent
							
								
									e5c7a71d8e
								
							
						
					
					
						commit
						6fd7361364
					
				|  | @ -59,13 +59,34 @@ func New( | |||
| 		mType: thisType, | ||||
| 	} | ||||
| 
 | ||||
| 	m.tags = []byte{} | ||||
| 	// pre-allocate exact size of the tags slice
 | ||||
| 	taglen := 0 | ||||
| 	for k, v := range tags { | ||||
| 		m.tags = append(m.tags, []byte(","+escaper.Replace(k))...) | ||||
| 		m.tags = append(m.tags, []byte("="+escaper.Replace(v))...) | ||||
| 		taglen += 2 + len(escaper.Replace(k)) + len(escaper.Replace(v)) | ||||
| 	} | ||||
| 	m.tags = make([]byte, taglen) | ||||
| 
 | ||||
| 	i := 0 | ||||
| 	for k, v := range tags { | ||||
| 		m.tags[i] = ',' | ||||
| 		i++ | ||||
| 		i += copy(m.tags[i:], escaper.Replace(k)) | ||||
| 		m.tags[i] = '=' | ||||
| 		i++ | ||||
| 		i += copy(m.tags[i:], escaper.Replace(v)) | ||||
| 	} | ||||
| 
 | ||||
| 	// pre-allocate capacity of the fields slice
 | ||||
| 	fieldlen := 0 | ||||
| 	for k, _ := range fields { | ||||
| 		// 10 bytes is completely arbitrary, but will at least prevent some
 | ||||
| 		// amount of allocations. There's a small possibility this will create
 | ||||
| 		// slightly more allocations for a metric that has many short fields.
 | ||||
| 		fieldlen += len(k) + 10 | ||||
| 	} | ||||
| 	m.fields = make([]byte, 0, fieldlen) | ||||
| 
 | ||||
| 	i = 0 | ||||
| 	for k, v := range fields { | ||||
| 		if i != 0 { | ||||
| 			m.fields = append(m.fields, ',') | ||||
|  | @ -138,7 +159,7 @@ func (m *metric) Point() *client.Point { | |||
| } | ||||
| 
 | ||||
| func (m *metric) String() string { | ||||
| 	return string(m.Serialize()) | ||||
| 	return string(m.name) + string(m.tags) + " " + string(m.fields) + " " + string(m.t) + "\n" | ||||
| } | ||||
| 
 | ||||
| func (m *metric) SetAggregate(b bool) { | ||||
|  | @ -154,24 +175,21 @@ func (m *metric) Type() telegraf.ValueType { | |||
| } | ||||
| 
 | ||||
| func (m *metric) Len() int { | ||||
| 	return len(m.name) + len(m.tags) + 1 + len(m.fields) + 1 + len(m.t) + 1 | ||||
| 	// 3 is for 2 spaces surrounding the fields array + newline at the end.
 | ||||
| 	return len(m.name) + len(m.tags) + len(m.fields) + len(m.t) + 3 | ||||
| } | ||||
| 
 | ||||
| func (m *metric) Serialize() []byte { | ||||
| 	tmp := make([]byte, m.Len()) | ||||
| 	i := 0 | ||||
| 	copy(tmp[i:], m.name) | ||||
| 	i += len(m.name) | ||||
| 	copy(tmp[i:], m.tags) | ||||
| 	i += len(m.tags) | ||||
| 	i += copy(tmp[i:], m.name) | ||||
| 	i += copy(tmp[i:], m.tags) | ||||
| 	tmp[i] = ' ' | ||||
| 	i++ | ||||
| 	copy(tmp[i:], m.fields) | ||||
| 	i += len(m.fields) | ||||
| 	i += copy(tmp[i:], m.fields) | ||||
| 	tmp[i] = ' ' | ||||
| 	i++ | ||||
| 	copy(tmp[i:], m.t) | ||||
| 	i += len(m.t) | ||||
| 	i += copy(tmp[i:], m.t) | ||||
| 	tmp[i] = '\n' | ||||
| 	return tmp | ||||
| } | ||||
|  | @ -307,12 +325,15 @@ func (m *metric) UnixNano() int64 { | |||
| } | ||||
| 
 | ||||
| func (m *metric) SetName(name string) { | ||||
| 	m.hashID = 0 | ||||
| 	m.name = []byte(nameEscaper.Replace(name)) | ||||
| } | ||||
| func (m *metric) SetPrefix(prefix string) { | ||||
| 	m.hashID = 0 | ||||
| 	m.name = append([]byte(nameEscaper.Replace(prefix)), m.name...) | ||||
| } | ||||
| func (m *metric) SetSuffix(suffix string) { | ||||
| 	m.hashID = 0 | ||||
| 	m.name = append(m.name, []byte(nameEscaper.Replace(suffix))...) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -36,10 +36,9 @@ func BenchmarkNewMetric(b *testing.B) { | |||
| 	s = string(mt.String()) | ||||
| } | ||||
| 
 | ||||
| func BenchmarkNewMetricAndInspect(b *testing.B) { | ||||
| 	var mt telegraf.Metric | ||||
| func BenchmarkTags(b *testing.B) { | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		mt, _ = New("test_metric", | ||||
| 		var mt, _ = New("test_metric", | ||||
| 			map[string]string{ | ||||
| 				"test_tag_1": "tag_value_1", | ||||
| 				"test_tag_2": "tag_value_2", | ||||
|  | @ -52,55 +51,32 @@ func BenchmarkNewMetricAndInspect(b *testing.B) { | |||
| 			}, | ||||
| 			time.Now(), | ||||
| 		) | ||||
| 		for k, v := range mt.Fields() { | ||||
| 			s = k | ||||
| 			I = v | ||||
| 		} | ||||
| 	} | ||||
| 	s = mt.String() | ||||
| } | ||||
| 
 | ||||
| func BenchmarkTags(b *testing.B) { | ||||
| 	var mt, _ = New("test_metric", | ||||
| 		map[string]string{ | ||||
| 			"test_tag_1": "tag_value_1", | ||||
| 			"test_tag_2": "tag_value_2", | ||||
| 			"test_tag_3": "tag_value_3", | ||||
| 		}, | ||||
| 		map[string]interface{}{ | ||||
| 			"string_field": "string", | ||||
| 			"int_field":    int64(1000), | ||||
| 			"float_field":  float64(2.1), | ||||
| 		}, | ||||
| 		time.Now(), | ||||
| 	) | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		tags = mt.Tags() | ||||
| 	} | ||||
| 	s = fmt.Sprint(tags) | ||||
| } | ||||
| 
 | ||||
| func BenchmarkFields(b *testing.B) { | ||||
| 	var mt, _ = New("test_metric", | ||||
| 		map[string]string{ | ||||
| 			"test_tag_1": "tag_value_1", | ||||
| 			"test_tag_2": "tag_value_2", | ||||
| 			"test_tag_3": "tag_value_3", | ||||
| 		}, | ||||
| 		map[string]interface{}{ | ||||
| 			"string_field": "string", | ||||
| 			"int_field":    int64(1000), | ||||
| 			"float_field":  float64(2.1), | ||||
| 		}, | ||||
| 		time.Now(), | ||||
| 	) | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		var mt, _ = New("test_metric", | ||||
| 			map[string]string{ | ||||
| 				"test_tag_1": "tag_value_1", | ||||
| 				"test_tag_2": "tag_value_2", | ||||
| 				"test_tag_3": "tag_value_3", | ||||
| 			}, | ||||
| 			map[string]interface{}{ | ||||
| 				"string_field": "string", | ||||
| 				"int_field":    int64(1000), | ||||
| 				"float_field":  float64(2.1), | ||||
| 			}, | ||||
| 			time.Now(), | ||||
| 		) | ||||
| 		fields = mt.Fields() | ||||
| 	} | ||||
| 	s = fmt.Sprint(fields) | ||||
| } | ||||
| 
 | ||||
| func BenchmarkSerializeMetric(b *testing.B) { | ||||
| func BenchmarkString(b *testing.B) { | ||||
| 	mt, _ := New("test_metric", | ||||
| 		map[string]string{ | ||||
| 			"test_tag_1": "tag_value_1", | ||||
|  | @ -121,7 +97,7 @@ func BenchmarkSerializeMetric(b *testing.B) { | |||
| 	s = S | ||||
| } | ||||
| 
 | ||||
| func BenchmarkSerializeMetricBytes(b *testing.B) { | ||||
| func BenchmarkSerialize(b *testing.B) { | ||||
| 	mt, _ := New("test_metric", | ||||
| 		map[string]string{ | ||||
| 			"test_tag_1": "tag_value_1", | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue