Avoid creating temporary objects in FiterValue().
It reduces the cpu time from 1000ns to 750ns
Test: statsd test.
Change-Id: Ifa7e98e3368f8d55f85c7b09d05a6c416482981d
diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp
index 6894bcf..b541612 100644
--- a/cmds/statsd/src/FieldValue.cpp
+++ b/cmds/statsd/src/FieldValue.cpp
@@ -135,6 +135,8 @@
case STRING:
str_value = from.str_value;
break;
+ default:
+ break;
}
}
@@ -148,6 +150,8 @@
return std::to_string(float_value) + "[F]";
case STRING:
return str_value + "[S]";
+ default:
+ return "[UNKNOWN]";
}
}
@@ -163,6 +167,8 @@
return float_value == that.float_value;
case STRING:
return str_value == that.str_value;
+ default:
+ return false;
}
}
@@ -177,6 +183,8 @@
return float_value != that.float_value;
case STRING:
return str_value != that.str_value;
+ default:
+ return false;
}
}
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
index d17dded..21f30e2 100644
--- a/cmds/statsd/src/FieldValue.h
+++ b/cmds/statsd/src/FieldValue.h
@@ -31,7 +31,7 @@
const int32_t kLastBitMask = 0x80;
const int32_t kClearLastBitDeco = 0x7f;
-enum Type { INT, LONG, FLOAT, STRING };
+enum Type { UNKNOWN, INT, LONG, FLOAT, STRING };
int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth);
@@ -82,6 +82,8 @@
int32_t mField;
public:
+ Field() {}
+
Field(int32_t tag, int32_t pos[], int32_t depth) : mTag(tag) {
mField = getEncodedField(pos, depth, true);
}
@@ -229,6 +231,8 @@
*
*/
struct Value {
+ Value() : type(UNKNOWN) {}
+
Value(int32_t v) {
int_value = v;
type = INT;
@@ -280,15 +284,13 @@
bool operator!=(const Value& that) const;
bool operator<(const Value& that) const;
-
-private:
- Value(){};
};
/**
* Represents a log item, or a dimension item (They are essentially the same).
*/
struct FieldValue {
+ FieldValue() {}
FieldValue(const Field& field, const Value& value) : mField(field), mValue(value) {
}
bool operator==(const FieldValue& that) const {
diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp
index d901bd6..7b21fb0 100644
--- a/cmds/statsd/src/HashableDimensionKey.cpp
+++ b/cmds/statsd/src/HashableDimensionKey.cpp
@@ -16,6 +16,8 @@
#define DEBUG false // STOPSHIP if true
#include "Log.h"
+#include <mutex>
+
#include "HashableDimensionKey.h"
#include "FieldValue.h"
@@ -48,6 +50,8 @@
hash = android::JenkinsHashMixBytes(hash, (uint8_t*)&floatVal, sizeof(float));
break;
}
+ default:
+ break;
}
}
return JenkinsHashWhiten(hash);
@@ -62,26 +66,32 @@
int prevAnyMatcherPrefix = 0;
size_t prevPrevFanout = 0;
size_t prevFanout = 0;
+
// For each matcher get matched results.
+ vector<FieldValue> matchedResults(2);
for (const auto& matcher : matcherFields) {
- vector<FieldValue> matchedResults;
+ size_t num_matches = 0;
for (const auto& value : values) {
// TODO: potential optimization here to break early because all fields are naturally
// sorted.
if (value.mField.matches(matcher)) {
- matchedResults.push_back(FieldValue(
- Field(value.mField.getTag(), (value.mField.getField() & matcher.mMask)),
- value.mValue));
+ if (num_matches >= matchedResults.size()) {
+ matchedResults.resize(num_matches * 2);
+ }
+ matchedResults[num_matches].mField.setTag(value.mField.getTag());
+ matchedResults[num_matches].mField.setField(value.mField.getField() & matcher.mMask);
+ matchedResults[num_matches].mValue = value.mValue;
+ num_matches++;
}
}
- if (matchedResults.size() == 0) {
+ if (num_matches == 0) {
VLOG("We can't find a dimension value for matcher (%d)%#x.", matcher.mMatcher.getTag(),
matcher.mMatcher.getField());
continue;
}
- if (matchedResults.size() == 1) {
+ if (num_matches == 1) {
for (auto& dimension : *output) {
dimension.addValue(matchedResults[0]);
}
@@ -117,23 +127,23 @@
// First create fanout (fanout size is matchedResults.Size which could be one,
// which means we do nothing here)
oldSize = output->size();
- for (size_t i = 1; i < matchedResults.size(); i++) {
+ for (size_t i = 1; i < num_matches; i++) {
output->insert(output->end(), output->begin(), output->begin() + oldSize);
}
prevPrevFanout = oldSize;
- prevFanout = matchedResults.size();
+ prevFanout = num_matches;
} else {
// If we should not create fanout, e.g., uid tag from same position should be remain
// together.
oldSize = prevPrevFanout;
- if (prevFanout != matchedResults.size()) {
+ if (prevFanout != num_matches) {
// sanity check.
ALOGE("2 Any matcher result in different output");
return false;
}
}
// now add the matched field value to output
- for (size_t i = 0; i < matchedResults.size(); i++) {
+ for (size_t i = 0; i < num_matches; i++) {
for (int j = 0; j < oldSize; j++) {
(*output)[i * oldSize + j].addValue(matchedResults[i]);
}
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 2c7b919..78ebe33 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -183,6 +183,8 @@
case STRING:
protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
break;
+ default:
+ break;
}
(*index)++;
} else if (valueDepth > depth && valuePrefix == prefix) {