allocation & perf improvements
This commit is contained in:
parent
e5c7a71d8e
commit
6fd7361364
|
@ -59,13 +59,34 @@ func New(
|
||||||
mType: thisType,
|
mType: thisType,
|
||||||
}
|
}
|
||||||
|
|
||||||
m.tags = []byte{}
|
// pre-allocate exact size of the tags slice
|
||||||
|
taglen := 0
|
||||||
for k, v := range tags {
|
for k, v := range tags {
|
||||||
m.tags = append(m.tags, []byte(","+escaper.Replace(k))...)
|
taglen += 2 + len(escaper.Replace(k)) + len(escaper.Replace(v))
|
||||||
m.tags = append(m.tags, []byte("="+escaper.Replace(v))...)
|
|
||||||
}
|
}
|
||||||
|
m.tags = make([]byte, taglen)
|
||||||
|
|
||||||
i := 0
|
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 {
|
for k, v := range fields {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
m.fields = append(m.fields, ',')
|
m.fields = append(m.fields, ',')
|
||||||
|
@ -138,7 +159,7 @@ func (m *metric) Point() *client.Point {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *metric) String() string {
|
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) {
|
func (m *metric) SetAggregate(b bool) {
|
||||||
|
@ -154,24 +175,21 @@ func (m *metric) Type() telegraf.ValueType {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *metric) Len() int {
|
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 {
|
func (m *metric) Serialize() []byte {
|
||||||
tmp := make([]byte, m.Len())
|
tmp := make([]byte, m.Len())
|
||||||
i := 0
|
i := 0
|
||||||
copy(tmp[i:], m.name)
|
i += copy(tmp[i:], m.name)
|
||||||
i += len(m.name)
|
i += copy(tmp[i:], m.tags)
|
||||||
copy(tmp[i:], m.tags)
|
|
||||||
i += len(m.tags)
|
|
||||||
tmp[i] = ' '
|
tmp[i] = ' '
|
||||||
i++
|
i++
|
||||||
copy(tmp[i:], m.fields)
|
i += copy(tmp[i:], m.fields)
|
||||||
i += len(m.fields)
|
|
||||||
tmp[i] = ' '
|
tmp[i] = ' '
|
||||||
i++
|
i++
|
||||||
copy(tmp[i:], m.t)
|
i += copy(tmp[i:], m.t)
|
||||||
i += len(m.t)
|
|
||||||
tmp[i] = '\n'
|
tmp[i] = '\n'
|
||||||
return tmp
|
return tmp
|
||||||
}
|
}
|
||||||
|
@ -307,12 +325,15 @@ func (m *metric) UnixNano() int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *metric) SetName(name string) {
|
func (m *metric) SetName(name string) {
|
||||||
|
m.hashID = 0
|
||||||
m.name = []byte(nameEscaper.Replace(name))
|
m.name = []byte(nameEscaper.Replace(name))
|
||||||
}
|
}
|
||||||
func (m *metric) SetPrefix(prefix string) {
|
func (m *metric) SetPrefix(prefix string) {
|
||||||
|
m.hashID = 0
|
||||||
m.name = append([]byte(nameEscaper.Replace(prefix)), m.name...)
|
m.name = append([]byte(nameEscaper.Replace(prefix)), m.name...)
|
||||||
}
|
}
|
||||||
func (m *metric) SetSuffix(suffix string) {
|
func (m *metric) SetSuffix(suffix string) {
|
||||||
|
m.hashID = 0
|
||||||
m.name = append(m.name, []byte(nameEscaper.Replace(suffix))...)
|
m.name = append(m.name, []byte(nameEscaper.Replace(suffix))...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,10 +36,9 @@ func BenchmarkNewMetric(b *testing.B) {
|
||||||
s = string(mt.String())
|
s = string(mt.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkNewMetricAndInspect(b *testing.B) {
|
func BenchmarkTags(b *testing.B) {
|
||||||
var mt telegraf.Metric
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
mt, _ = New("test_metric",
|
var mt, _ = New("test_metric",
|
||||||
map[string]string{
|
map[string]string{
|
||||||
"test_tag_1": "tag_value_1",
|
"test_tag_1": "tag_value_1",
|
||||||
"test_tag_2": "tag_value_2",
|
"test_tag_2": "tag_value_2",
|
||||||
|
@ -52,55 +51,32 @@ func BenchmarkNewMetricAndInspect(b *testing.B) {
|
||||||
},
|
},
|
||||||
time.Now(),
|
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()
|
tags = mt.Tags()
|
||||||
}
|
}
|
||||||
s = fmt.Sprint(tags)
|
s = fmt.Sprint(tags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkFields(b *testing.B) {
|
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++ {
|
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()
|
fields = mt.Fields()
|
||||||
}
|
}
|
||||||
s = fmt.Sprint(fields)
|
s = fmt.Sprint(fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkSerializeMetric(b *testing.B) {
|
func BenchmarkString(b *testing.B) {
|
||||||
mt, _ := New("test_metric",
|
mt, _ := New("test_metric",
|
||||||
map[string]string{
|
map[string]string{
|
||||||
"test_tag_1": "tag_value_1",
|
"test_tag_1": "tag_value_1",
|
||||||
|
@ -121,7 +97,7 @@ func BenchmarkSerializeMetric(b *testing.B) {
|
||||||
s = S
|
s = S
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkSerializeMetricBytes(b *testing.B) {
|
func BenchmarkSerialize(b *testing.B) {
|
||||||
mt, _ := New("test_metric",
|
mt, _ := New("test_metric",
|
||||||
map[string]string{
|
map[string]string{
|
||||||
"test_tag_1": "tag_value_1",
|
"test_tag_1": "tag_value_1",
|
||||||
|
|
Loading…
Reference in New Issue