perf($parse): improve performance of assignment expressions
There was a ~5% improvement in the added `parsed-expressions-bp/assignment` benchmark (which only contains assignment expressions). In real-world applications, the time spent in assignment expressions will be a tiny fragment of the overall processing time, though. Closes #14957
This commit is contained in:
@@ -23,7 +23,6 @@ app.directive('bmPeWatch', function() {
|
||||
return function($scope, $element, $attrs) {
|
||||
$scope.$watch($attrs.bmPeWatch, function(val) {
|
||||
$element.text(val);
|
||||
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -55,19 +54,19 @@ app.controller('DataController', function($scope, $rootScope) {
|
||||
|
||||
var star = '*';
|
||||
|
||||
$scope.func = function() { return star;};
|
||||
$scope.func = function() { return star; };
|
||||
|
||||
for (var i = 0; i < totalRows; i++) {
|
||||
data.push({
|
||||
index: i,
|
||||
odd: i % 2 === 0,
|
||||
even: i % 2 === 1,
|
||||
str0: "foo-" + Math.random() * Date.now(),
|
||||
str1: "bar-" + Math.random() * Date.now(),
|
||||
str2: "baz-" + Math.random() * Date.now(),
|
||||
num0: Math.random() * Date.now(),
|
||||
num1: Math.random() * Date.now(),
|
||||
num2: Math.random() * Date.now(),
|
||||
odd: i % 2 === 0,
|
||||
even: i % 2 === 1,
|
||||
str0: 'foo-' + Math.random() * Date.now(),
|
||||
str1: 'bar-' + Math.random() * Date.now(),
|
||||
str2: 'baz-' + Math.random() * Date.now(),
|
||||
num0: Math.random() * Date.now(),
|
||||
num1: Math.random() * Date.now(),
|
||||
num2: Math.random() * Date.now(),
|
||||
date0: new Date(Math.random() * Date.now()),
|
||||
date1: new Date(Math.random() * Date.now()),
|
||||
date2: new Date(Math.random() * Date.now()),
|
||||
|
||||
@@ -52,6 +52,11 @@
|
||||
<label for="functionCalls">Function calls</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="assignment" id="assignment">
|
||||
<label for="assignment">Assignment</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="objectLiterals" id="objectLiterals">
|
||||
<label for="objectLiterals">Object Literals</label>
|
||||
@@ -197,6 +202,18 @@
|
||||
<span bm-pe-watch="row.func(row.func(), row.func())"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="assignment" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="row.foo = row.str0"></span>
|
||||
<span bm-pe-watch="row.obj.foo = row.str1"></span>
|
||||
<span bm-pe-watch="row.obj.obj.foo = row.str2"></span>
|
||||
<span bm-pe-watch="row['bar'] = row.num0"></span>
|
||||
<span bm-pe-watch="row.obj['bar'] = row.num1"></span>
|
||||
<span bm-pe-watch="row.obj.obj['bar'] = row.num2"></span>
|
||||
<span bm-pe-watch="row[0] = row.date0"></span>
|
||||
<span bm-pe-watch="row.obj[0] = row.date1"></span>
|
||||
<span bm-pe-watch="row.obj.obj[0] = row.date2"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="objectLiterals" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch-literal="{foo: rowIdx}"></span>
|
||||
<span bm-pe-watch-literal="{foo: row, bar: rowIdx}"></span>
|
||||
|
||||
+31
-25
@@ -13,6 +13,25 @@
|
||||
|
||||
var $parseMinErr = minErr('$parse');
|
||||
|
||||
var ARRAY_CTOR = [].constructor;
|
||||
var BOOLEAN_CTOR = (false).constructor;
|
||||
var FUNCTION_CTOR = Function.constructor;
|
||||
var NUMBER_CTOR = (0).constructor;
|
||||
var OBJECT_CTOR = {}.constructor;
|
||||
var STRING_CTOR = ''.constructor;
|
||||
var ARRAY_CTOR_PROTO = ARRAY_CTOR.prototype;
|
||||
var BOOLEAN_CTOR_PROTO = BOOLEAN_CTOR.prototype;
|
||||
var FUNCTION_CTOR_PROTO = FUNCTION_CTOR.prototype;
|
||||
var NUMBER_CTOR_PROTO = NUMBER_CTOR.prototype;
|
||||
var OBJECT_CTOR_PROTO = OBJECT_CTOR.prototype;
|
||||
var STRING_CTOR_PROTO = STRING_CTOR.prototype;
|
||||
|
||||
var CALL = FUNCTION_CTOR_PROTO.call;
|
||||
var APPLY = FUNCTION_CTOR_PROTO.apply;
|
||||
var BIND = FUNCTION_CTOR_PROTO.bind;
|
||||
|
||||
var objectValueOf = OBJECT_CTOR_PROTO.valueOf;
|
||||
|
||||
// Sandboxing Angular Expressions
|
||||
// ------------------------------
|
||||
// Angular expressions are generally considered safe because these expressions only have direct
|
||||
@@ -93,10 +112,6 @@ function ensureSafeObject(obj, fullExpression) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
var CALL = Function.prototype.call;
|
||||
var APPLY = Function.prototype.apply;
|
||||
var BIND = Function.prototype.bind;
|
||||
|
||||
function ensureSafeFunction(obj, fullExpression) {
|
||||
if (obj) {
|
||||
if (obj.constructor === obj) {
|
||||
@@ -113,25 +128,18 @@ function ensureSafeFunction(obj, fullExpression) {
|
||||
|
||||
function ensureSafeAssignContext(obj, fullExpression) {
|
||||
if (obj) {
|
||||
var booleanConstructor = (false).constructor;
|
||||
var numberConstructor = (0).constructor;
|
||||
var stringConstructor = ''.constructor;
|
||||
var objectConstructor = {}.constructor;
|
||||
var arrayConstructor = [].constructor;
|
||||
var functionConstructor = Function.constructor;
|
||||
|
||||
if (obj === booleanConstructor ||
|
||||
obj === numberConstructor ||
|
||||
obj === stringConstructor ||
|
||||
obj === objectConstructor ||
|
||||
obj === arrayConstructor ||
|
||||
obj === functionConstructor ||
|
||||
obj === booleanConstructor.prototype ||
|
||||
obj === numberConstructor.prototype ||
|
||||
obj === stringConstructor.prototype ||
|
||||
obj === objectConstructor.prototype ||
|
||||
obj === arrayConstructor.prototype ||
|
||||
obj === functionConstructor.prototype) {
|
||||
if (obj === ARRAY_CTOR ||
|
||||
obj === BOOLEAN_CTOR ||
|
||||
obj === FUNCTION_CTOR ||
|
||||
obj === NUMBER_CTOR ||
|
||||
obj === OBJECT_CTOR ||
|
||||
obj === STRING_CTOR ||
|
||||
obj === ARRAY_CTOR_PROTO ||
|
||||
obj === BOOLEAN_CTOR_PROTO ||
|
||||
obj === FUNCTION_CTOR_PROTO ||
|
||||
obj === NUMBER_CTOR_PROTO ||
|
||||
obj === OBJECT_CTOR_PROTO ||
|
||||
obj === STRING_CTOR_PROTO) {
|
||||
throw $parseMinErr('isecaf',
|
||||
'Assigning to a constructor or its prototype is disallowed! Expression: {0}',
|
||||
fullExpression);
|
||||
@@ -1794,8 +1802,6 @@ function isPossiblyDangerousMemberName(name) {
|
||||
return name === 'constructor';
|
||||
}
|
||||
|
||||
var objectValueOf = Object.prototype.valueOf;
|
||||
|
||||
function getValueOf(value) {
|
||||
return isFunction(value.valueOf) ? value.valueOf() : objectValueOf.call(value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user