Skip to content

Commit 0273cfe

Browse files
committed
perf: push targetingRuleConditionValuesTypesFromValues down
validSemver is super-slow, so having it on the hot path in evaluateCondition adds a ton of overhead (as in, >50%).
1 parent 0fae041 commit 0273cfe

File tree

1 file changed

+45
-49
lines changed

1 file changed

+45
-49
lines changed

src/rules.ts

Lines changed: 45 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,6 @@ function evaluateRuleConditions(
154154
function evaluateCondition(subjectAttributes: Record<string, any>, condition: Condition): boolean {
155155
const value = subjectAttributes[condition.attribute];
156156

157-
const conditionValueType = targetingRuleConditionValuesTypesFromValues(condition.value);
158-
159157
if (condition.operator === OperatorType.IS_NULL) {
160158
if (condition.value) {
161159
return value === null || value === undefined;
@@ -166,25 +164,32 @@ function evaluateCondition(subjectAttributes: Record<string, any>, condition: Co
166164
if (value != null) {
167165
switch (condition.operator) {
168166
case OperatorType.GTE:
169-
if (conditionValueType === OperatorValueType.SEM_VER) {
170-
return compareSemVer(value, condition.value, semverGte);
171-
}
172-
return compareNumber(value, condition.value, (a, b) => a >= b);
173167
case OperatorType.GT:
174-
if (conditionValueType === OperatorValueType.SEM_VER) {
175-
return compareSemVer(value, condition.value, semverGt);
176-
}
177-
return compareNumber(value, condition.value, (a, b) => a > b);
178168
case OperatorType.LTE:
169+
case OperatorType.LT: {
170+
const conditionValueType = targetingRuleConditionValuesTypesFromValues(condition.value);
179171
if (conditionValueType === OperatorValueType.SEM_VER) {
180-
return compareSemVer(value, condition.value, semverLte);
181-
}
182-
return compareNumber(value, condition.value, (a, b) => a <= b);
183-
case OperatorType.LT:
184-
if (conditionValueType === OperatorValueType.SEM_VER) {
185-
return compareSemVer(value, condition.value, semverLt);
172+
const comparator =
173+
condition.operator === OperatorType.GTE
174+
? semverGte
175+
: condition.operator === OperatorType.GT
176+
? semverGt
177+
: condition.operator === OperatorType.LTE
178+
? semverLte
179+
: semverLt;
180+
return compareSemVer(value, condition.value, comparator);
186181
}
187-
return compareNumber(value, condition.value, (a, b) => a < b);
182+
183+
const comparator = (a: number, b: number) =>
184+
condition.operator === OperatorType.GTE
185+
? a >= b
186+
: condition.operator === OperatorType.GT
187+
? a > b
188+
: condition.operator === OperatorType.LTE
189+
? a <= b
190+
: a < b;
191+
return compareNumber(value, condition.value, comparator);
192+
}
188193
case OperatorType.MATCHES:
189194
return new RegExp(condition.value as string).test(value as string);
190195
case OperatorType.NOT_MATCHES:
@@ -203,7 +208,6 @@ function evaluateObfuscatedCondition(
203208
condition: Condition,
204209
): boolean {
205210
const value = hashedSubjectAttributes[condition.attribute];
206-
const conditionValueType = targetingRuleConditionValuesTypesFromValues(value);
207211

208212
if (condition.operator === ObfuscatedOperatorType.IS_NULL) {
209213
if (condition.value === getMD5Hash('true')) {
@@ -215,41 +219,33 @@ function evaluateObfuscatedCondition(
215219
if (value != null) {
216220
switch (condition.operator) {
217221
case ObfuscatedOperatorType.GTE:
218-
if (conditionValueType === OperatorValueType.SEM_VER) {
219-
return compareSemVer(value, decodeBase64(condition.value as string), semverGte);
220-
}
221-
return compareNumber(
222-
value,
223-
Number(decodeBase64(condition.value as string)),
224-
(a, b) => a >= b,
225-
);
226222
case ObfuscatedOperatorType.GT:
227-
if (conditionValueType === OperatorValueType.SEM_VER) {
228-
return compareSemVer(value, decodeBase64(condition.value as string), semverGt);
229-
}
230-
return compareNumber(
231-
value,
232-
Number(decodeBase64(condition.value as string)),
233-
(a, b) => a > b,
234-
);
235223
case ObfuscatedOperatorType.LTE:
224+
case ObfuscatedOperatorType.LT: {
225+
const conditionValue = decodeBase64(condition.value);
226+
const conditionValueType = targetingRuleConditionValuesTypesFromValues(conditionValue);
236227
if (conditionValueType === OperatorValueType.SEM_VER) {
237-
return compareSemVer(value, decodeBase64(condition.value as string), semverLte);
228+
const comparator =
229+
condition.operator === ObfuscatedOperatorType.GTE
230+
? semverGte
231+
: condition.operator === ObfuscatedOperatorType.GT
232+
? semverGt
233+
: condition.operator === ObfuscatedOperatorType.LTE
234+
? semverLte
235+
: semverLt;
236+
return compareSemVer(value, conditionValue, comparator);
238237
}
239-
return compareNumber(
240-
value,
241-
Number(decodeBase64(condition.value as string)),
242-
(a, b) => a <= b,
243-
);
244-
case ObfuscatedOperatorType.LT:
245-
if (conditionValueType === OperatorValueType.SEM_VER) {
246-
return compareSemVer(value, decodeBase64(condition.value as string), semverLt);
247-
}
248-
return compareNumber(
249-
value,
250-
Number(decodeBase64(condition.value as string)),
251-
(a, b) => a < b,
252-
);
238+
239+
const comparator = (a: number, b: number) =>
240+
condition.operator === ObfuscatedOperatorType.GTE
241+
? a >= b
242+
: condition.operator === ObfuscatedOperatorType.GT
243+
? a > b
244+
: condition.operator === ObfuscatedOperatorType.LTE
245+
? a <= b
246+
: a < b;
247+
return compareNumber(value, Number(conditionValue), comparator);
248+
}
253249
case ObfuscatedOperatorType.MATCHES:
254250
return new RegExp(decodeBase64(condition.value as string)).test(value as string);
255251
case ObfuscatedOperatorType.NOT_MATCHES:

0 commit comments

Comments
 (0)