attributes
is an array with all attributes selected by the user.
attributeList
is a Mongo collection declared in [root]/lib and contains all possible attributes.
I'm using two loops in order to match attributes. For those that match, new fields "operator" and "value" are added and will be used in the template.
Do you see a way how to improve these two loops in terms of speed?
var attibutes = attrInfo2.findOne({}, {"fields": {"metric": 1}, reactive: false});
var result = attributeList.find(query).map(function (attr) {
if(attr.inputType) {
if (attr.inputType === "int" || attr.inputType === "double") {
_.map(attibutes.metric, function (m) {
var operator;
if (m.attrType === "filter" && attr.field === _.values(m.attrField)[0]) {
if (_.isObject(m.attrData)) {
operator = _.keys(m.attrData)[0];
if (operator !== "in") {
attr.operator = operator;
}
attr.value = _.values(m.attrData)[0];
} else {
attr.value = m.attrData;
}
}
return m;
});
} else if (attr.inputType === "string"){
_.map(attibutes.metric, function (m) {
if (m.attrType === "filter" && attr.field === _.values(m.attrField)[0]) {
if (_.isObject(m.attrData)) {
attr.value = _.values(m.attrData)[0];
} else{
attr.value = m.attrData;
}
}
return m;
});
}
}
return attr;
});
1 Answer 1
Generally speaking, I'd avoid relying heavily on function calls if speed is important. Specifically:
_.map(attibutes.metric, function (m)
If attibutes.metric is an array I'd do
var i = attibutes.metric.length;
while(i--) {
/* your code here */
}
or
var i, length = attibutes.metric.length;
for (i = 0; i < length; i++) {
/* your code here */
}
depending on the engine, the while loop will be faster than the for or vice-versa.
if attibutes.metric is an object I'd do
keys = Object.keys(attibutes.metric);
for (var key in keys) {
/* your code here */
}
Any of those constructs is probably faster than calling _.map (you should still profile it, YMMV).
second, i'd invert
if (_.isObject(m.attrData) {
if the alternative is m.attrData is a primitive type, so
if (typeof m.attrData === 'string') { // replace string with whatever primitive
attr.value = _.values(m.attrData)[0];
} else {
operator = _.keys(m.attrData)[0];
if (operator !== "in") {
attr.operator = operator;
}
attr.value = m.attrData;
}