Avoid creating objects when calling Hashtable.values() and by using gdjs.staticArray

This commit is contained in:
Florian Rival
2016-04-28 23:16:38 +02:00
parent 6625e3fd00
commit c7cd582152
5 changed files with 73 additions and 47 deletions

View File

@@ -538,8 +538,11 @@ gdjs.PhysicsRuntimeBehavior.prototype.collisionWith = function( otherObjectsTabl
if ( this._box2DBody === null ) this.createBody();
//Getting a list of all objects which are tested
var objects = [];
var objectsLists = otherObjectsTable.values();
var objects = gdjs.staticArray(gdjs.PhysicsRuntimeBehavior.prototype.collisionWith);
objects.length = 0;
var objectsLists = gdjs.staticArray2(gdjs.PhysicsRuntimeBehavior.prototype.collisionWith);
otherObjectsTable.values(objectsLists);
for(var i = 0, len = objectsLists.length;i<len;++i) {
objects.push.apply(objects, objectsLists[i]);

View File

@@ -23,9 +23,11 @@ gdjs.evtTools.object = gdjs.evtTools.object || {};
* @static
*/
gdjs.evtTools.object.pickOnly = function(objectsLists, runtimeObject) {
var values = objectsLists.values();
for(var i = 0, len = values.length;i<len;++i)
values[i].length = 0; //Be sure not to lose the reference to the original array
var lists = gdjs.staticArray(gdjs.evtTools.object.pickOnly);
objectsLists.values(lists);
for(var i = 0, len = lists.length;i<len;++i)
lists[i].length = 0; //Be sure not to lose the reference to the original array
objectsLists.get(runtimeObject.getName()).push(runtimeObject);
};
@@ -54,17 +56,19 @@ gdjs.evtTools.object.pickOnly = function(objectsLists, runtimeObject) {
gdjs.evtTools.object.twoListsTest = function(predicate, objectsLists1, objectsLists2, inverted) {
var isTrue = false;
var objects1Values = objectsLists1.values();
var objects2Values = objectsLists2.values();
var objects1Lists = gdjs.staticArray(gdjs.evtTools.object.twoListsTest);
objectsLists1.values(objects1Lists);
var objects2Lists = gdjs.staticArray2(gdjs.evtTools.object.twoListsTest);
objectsLists2.values(objects2Lists);
for(var i = 0, leni = objects1Values.length;i<leni;++i) {
var arr = objects1Values[i];
for(var i = 0, leni = objects1Lists.length;i<leni;++i) {
var arr = objects1Lists[i];
for(var k = 0, lenk = arr.length;k<lenk;++k) {
arr[k].pick = false;
}
}
for(var i = 0, leni = objects2Values.length;i<leni;++i) {
var arr = objects2Values[i];
for(var i = 0, leni = objects2Lists.length;i<leni;++i) {
var arr = objects2Lists[i];
for(var k = 0, lenk = arr.length;k<lenk;++k) {
arr[k].pick = false;
}
@@ -72,14 +76,14 @@ gdjs.evtTools.object.twoListsTest = function(predicate, objectsLists1, objectsLi
//Launch the function for each object of the first list with each object
//of the second list.
for(var i = 0, leni = objects1Values.length;i<leni;++i) {
var arr1 = objects1Values[i];
for(var i = 0, leni = objects1Lists.length;i<leni;++i) {
var arr1 = objects1Lists[i];
for(var k = 0, lenk = arr1.length;k<lenk;++k) {
var atLeastOneObject = false;
for(var j = 0, lenj = objects2Values.length;j<lenj;++j) {
var arr2 = objects2Values[j];
for(var j = 0, lenj = objects2Lists.length;j<lenj;++j) {
var arr2 = objects2Lists[j];
for(var l = 0, lenl = arr2.length;l<lenl;++l) {
if (arr1[k].pick && arr2[l].pick) continue; //Avoid unnecessary costly call to predicate.
@@ -107,8 +111,8 @@ gdjs.evtTools.object.twoListsTest = function(predicate, objectsLists1, objectsLi
}
//Trim not picked objects from lists.
for(var i = 0, leni = objects1Values.length;i<leni;++i) {
var arr = objects1Values[i];
for(var i = 0, leni = objects1Lists.length;i<leni;++i) {
var arr = objects1Lists[i];
var finalSize = 0;
for(var k = 0, lenk = arr.length;k<lenk;++k) {
@@ -122,8 +126,8 @@ gdjs.evtTools.object.twoListsTest = function(predicate, objectsLists1, objectsLi
}
if ( !inverted ) {
for(var i = 0, leni = objects2Values.length;i<leni;++i) {
var arr = objects2Values[i];
for(var i = 0, leni = objects2Lists.length;i<leni;++i) {
var arr = objects2Lists[i];
var finalSize = 0;
for(var k = 0, lenk = arr.length;k<lenk;++k) {
@@ -155,19 +159,20 @@ gdjs.evtTools.object.twoListsTest = function(predicate, objectsLists1, objectsLi
*/
gdjs.evtTools.object.pickObjectsIf = function(predicate, objectsLists, negatePredicate) {
var isTrue = false;
var objectsValues = objectsLists.values();
var lists = gdjs.staticArray(gdjs.evtTools.object.pickObjectsIf);
objectsLists.values(lists);
//Create a boolean for each object
for(var i = 0, leni = objectsValues.length;i<leni;++i) {
var arr = objectsValues[i];
for(var i = 0, leni = lists.length;i<leni;++i) {
var arr = lists[i];
for(var k = 0, lenk = arr.length;k<lenk;++k) {
arr[k].pick = false;
}
}
//Pick only objects that are fulfilling the predicate
for(var i = 0, leni = objectsValues.length;i<leni;++i) {
var arr = objectsValues[i];
for(var i = 0, leni = lists.length;i<leni;++i) {
var arr = lists[i];
for(var k = 0, lenk = arr.length;k<lenk;++k) {
if (negatePredicate ^ predicate(arr[k])) {
@@ -178,8 +183,8 @@ gdjs.evtTools.object.pickObjectsIf = function(predicate, objectsLists, negatePre
}
//Trim not picked objects from lists.
for(var i = 0, leni = objectsValues.length;i<leni;++i) {
var arr = objectsValues[i];
for(var i = 0, leni = lists.length;i<leni;++i) {
var arr = lists[i];
var finalSize = 0;
for(var k = 0, lenk = arr.length;k<lenk;++k) {
@@ -260,11 +265,14 @@ gdjs.evtTools.object.pickRandomObject = function(runtimeScene, objectsLists) {
//Create a list with all the objects
//and clear the lists of picked objects.
var objects = [];
var values = objectsLists.values();
for(var i = 0, len = values.length;i<len;++i) {
objects.push.apply(objects, values[i]);
values[i].length = 0; //Be sure not to lose the reference to the original array
var objects = gdjs.staticArray(gdjs.evtTools.object.pickRandomObject);
objects.length = 0;
var lists = gdjs.staticArray2(gdjs.evtTools.object.pickRandomObject);
objectsLists.values(lists);
for(var i = 0, len = lists.length;i<len;++i) {
objects.push.apply(objects, lists[i]);
lists[i].length = 0; //Be sure not to lose the reference to the original array
}
//Pick only one object
@@ -284,9 +292,10 @@ gdjs.evtTools.object.pickNearestObject = function(objectsLists, x, y, inverted)
var bestObject = null;
var best = 0;
var first = true;
var values = objectsLists.values();
for(var i = 0, len = values.length;i<len;++i) {
var list = values[i];
var lists = gdjs.staticArray(gdjs.evtTools.object.pickNearestObject);
objectsLists.values(lists);
for(var i = 0, len = lists.length;i<len;++i) {
var list = lists[i];
for(var j = 0;j < list.length;++j) {
var object = list[j];
@@ -349,11 +358,11 @@ gdjs.evtTools.object.createObjectFromGroupOnScene = function(runtimeScene, objec
* @private
*/
gdjs.evtTools.object.pickedObjectsCount = function(objectsLists) {
var size = 0;
var values = objectsLists.values();
for(var i = 0, len = values.length;i<len;++i) {
size += values[i].length;
var lists = gdjs.staticArray(gdjs.evtTools.object.pickedObjectsCount);
objectsLists.values(lists);
for(var i = 0, len = lists.length;i<len;++i) {
size += lists[i].length;
}
return size;

View File

@@ -190,6 +190,16 @@ gdjs.getBehaviorConstructor = function(name) {
return gdjs.behaviorsTypes.get(""); //Create a base empty runtime behavior.
};
gdjs.staticArray = function(owner) {
owner._staticArray = owner._staticArray || [];
return owner._staticArray;
}
gdjs.staticArray2 = function(owner) {
owner._staticArray2 = owner._staticArray2 || [];
return owner._staticArray2;
}
Array.prototype.remove = function(from) {
//Adapted from the nice article available at
//https://www.scirra.com/blog/76/how-to-write-low-garbage-real-time-javascript

View File

@@ -39,15 +39,13 @@ Hashtable.prototype.keys = function(result) {
}
}
Hashtable.prototype.values = function() {
//TODO: search for functions calling values() and avoid doing it.
var values = [];
Hashtable.prototype.values = function(result) {
result.length = 0;
for (var k in this.items) {
if (this.items.hasOwnProperty(k)) {
values.push(this.items[k]);
result.push(this.items[k]);
}
}
return values;
}
Hashtable.prototype.clear = function() {

View File

@@ -997,8 +997,11 @@ gdjs.RuntimeObject.prototype.putAroundObject = function(obj,distance,angleInDegr
gdjs.RuntimeObject.prototype.separateObjectsWithoutForces = function(objectsLists) {
//Prepare the list of objects to iterate over.
var objects = [];
var lists = objectsLists.values();
var objects = gdjs.staticArray(gdjs.RuntimeObject.prototype.separateObjectsWithoutForces);
objects.length = 0;
var lists = gdjs.staticArray2(gdjs.RuntimeObject.prototype.separateObjectsWithoutForces);
objectsLists.values(lists);
for(var i = 0, len = lists.length;i<len;++i) {
objects.push.apply(objects, lists[i]);
}
@@ -1032,8 +1035,11 @@ gdjs.RuntimeObject.prototype.separateObjectsWithForces = function(objectsLists,
if ( len == undefined ) len = 10;
//Prepare the list of objects to iterate over.
var objects = [];
var lists = objectsLists.values();
var objects = gdjs.staticArray(gdjs.RuntimeObject.prototype.separateObjectsWithForces);
objects.length = 0;
var lists = gdjs.staticArray2(gdjs.RuntimeObject.prototype.separateObjectsWithForces);
objectsLists.values(lists);
for(var i = 0, len = lists.length;i<len;++i) {
objects.push.apply(objects, lists[i]);
}