FredericCox
%Europe/Berlin %406 %2008, 10:45
Een performance topic, dit wordt zo hard over het hoofd gezien heb ik de indruk, daarom zou ik deze topic willen gebruiken om te spreken over concrete bottlenecks en mogelijke oplossingen.
Zelf start ik met een kleine hang die ik aan het begin van mijn applicatie heb.
Dit omdat de functie vele for loops bevat die zoeken in objecten. Ik heb de functie opgesplitst in kleinere functies en de for loops getyped als Number
for(var i:Number = 0;i<data.length;i++)
Zijn er nog tips of zaken die ik kan proberen om die hang te voorkomen? Site mag iets langer laden zolang die maar niet blijft hangen.
Voor wie geinteresseerd is in de code (die herschreven moet worden vanaf nul binnenkort, ik weet het! :) )
public function createSearchProvider(module:String):void{
relevantFilterData = new Object();
//create the provider for filters and search box
if(availableFilters.length < 1){
availableFilters = new ArrayCollection([
{filterBox:this.CategorySearch, filterContainer:'categories', filterName:'category'},
{filterBox:this.BrandSearch, filterContainer:'brands', filterName:'brand'},
{filterBox:this.TopicSearch, filterContainer:'topics', filterName:'topic'},
{filterBox:this.StyleSearch, filterContainer:'styles', filterName:'style'}
]);
}
// var modules:Array = new Array("video","hopping","blog");
var moduleObject:Object = this[module+"Data"];
//set up the search data for each module (search in title/name, description/content, address, phoneNumber, brands, styles, topics, categories
moduleObject.moduleName = module;
moduleObject.brandProvider = getRelevantFilterData("brand",module);
moduleObject.categoryProvider = getRelevantFilterData("category",module);
moduleObject.styleProvider = getRelevantFilterData("style",module);
moduleObject.topicProvider = getRelevantFilterData("topic",module);
this.callLater(setupProvider,[module]);
}
private function setupProvider(module:String):void{
for(var a:Number = 0;a<availableFilters.length;a++){
var filter:Object = availableFilters[a];
determineSearchProvider(filter, module);
}
}
public function determineSearchProvider(filter:Object, module:String):void{
//To optimize search speed we already assign an array of id's to a filter where the item contains this filtervalue
var content:ArrayCollection;
var node:*;
switch(module){
case 'video':
content = this.parentDocument.videos;
break;
case 'hopping':
content = this.parentDocument.pois;
break;
case 'blog':
content = this.parentDocument.blogitems;
break;
}
for(var p:Number = 0;p<content.length;p++){
//for every item check if it matches the filters contents
var _check:Boolean = true;
switch(module){
case 'video':
try{
node = content[p][filter.filterContainer][filter.filterName];
}catch(err:Error){
var _check:Boolean = false;
}
break;
case 'hopping':
try{
node = content[p].poidetails[filter.filterContainer][filter.filterName];
}catch(err:Error){
var _check:Boolean = false;
}
break;
case 'blog':
try{
node = content[p][filter.filterContainer][filter.filterName];
}catch(err:Error){
var _check:Boolean = false;
}
break;
}
var filterValues:ArrayCollection = this[module+"Data"][filter.filterName+"Provider"];
for(var c:Number = 0; c<filterValues.length;c++){ //resultaat is bvb Kleding
if(_check){
//var _collection:* = node;
if(node is ArrayCollection){
for(var f:Number = 0;f<node.length;f++){
if(node[f].name.toLowerCase() == filterValues[c].name.toLowerCase()){
//this.parentDocument.debug.text += pois[p].poidetails.name + " behoort tot de " + filter.filterName + " " + hoppingData[filter.filterName+"Provider"][c].name + "\n";
//een filter(bvb category(kleding)) komt overeen met een filter uit de poi (kleding == kleding)
//dus moeten we kijken of deze winkel al eens is toegevoegd en anders dit id toevoegen aan de relevantKleding arrayCollection(id, module, matchType)
//als de relevant array nog niet bestaat maken we deze aan
if(this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()] == null){
this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()] = new ArrayCollection();
//add the new id to the arraycollection
var obj:Object = new Object;
obj.id = content[p].id;
obj.matchType = filter.filterName;
obj.module = module;
this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()].addItem(obj);
}else{
var found:Boolean = false;
for(var r:Number = 0;r<this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()].length;r++){
if(this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()][r] == content[p].id){
//Alert.show(pois[p].poidetails.name + "heeft meerdere ... ? en zit al in de array");
found = true;
}
}
if(!found){
//add the new id to the arraycollection
var obj:Object = new Object;
obj.id = content[p].id;
obj.matchType = filter.filterName;
obj.module = module;
this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()].addItem(obj);
}
}
}
}//end for
}else{
if(node.name.toLowerCase() == filterValues[c].name.toLowerCase()){
//this.parentDocument.debug.text += pois[p].poidetails.name + " behoort tot de " + filter.filterName + " " + hoppingData[filter.filterName+"Provider"][c].name + "\n";
//een filter(bvb category(kleding)) komt overeen met een filter uit de poi (kleding == kleding)
//dus moeten we kijken of deze winkel al eens is toegevoegd en anders dit id toevoegen aan de relevantKleding arrayCollection(id, module, matchType)
//als de relevant array nog niet bestaat maken we deze aan
if(this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()] == null){
this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()] = new ArrayCollection();
//add the new id to the arraycollection
var obj:Object = new Object;
obj.id = content[p].id;
obj.matchType = filter.filterName;
obj.module = module;
this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()].addItem(obj);
}else{
var found:Boolean = false;
for(var r:Number = 0;r<this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()].length;r++){
if(this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()][r] == content[p].id){
found = true;
}
}
if(!found){
//add the new id to the arraycollection
var obj:Object = new Object;
obj.id = content[p].id;
obj.matchType = filter.filterName;
obj.module = module;
this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()].addItem(obj);
}
}
}
}
}else{
//node is niet bruikbaar(ingevuld)
}
}
}
}
//this function determines which categories are in the dataProvider of the content and returns a dataProvider for the filterMenu
public var relevantFilterData:Object = new Object;
private function getRelevantFilterData(filter:String, moduleName:String = null):ArrayCollection{
if(moduleName == null){
moduleName = Application.application.moduleName;
}
//and set the one we return
var returnProvider:ArrayCollection = new ArrayCollection;
var content:ArrayCollection;
var isDetails:Boolean = false;
switch(moduleName){
case 'video':
content = this.parentDocument.videos;
break;
case 'hopping':
content = this.parentDocument.pois;
isDetails = true;
break;
case 'blog':
content = this.parentDocument.blogitems;
break;
}
content.filterFunction = null;
content.refresh();
returnProvider = returnCollectionForMenuFilter(content, filter, isDetails);
return returnProvider;
}
private function returnCollectionForMenuFilter(content:ArrayCollect ion, filter:String, isDetails:Boolean = false):ArrayCollection{
//determine which content we use
var returnProvider:ArrayCollection = new ArrayCollection;
var possibleFilters:ArrayCollection = new ArrayCollection([
{filterBox: this.CategorySearch, collectionName:'categories', objectName:'category'},
{filterBox: this.BrandSearch, collectionName:'brands', objectName:'brand'},
{filterBox: this.TopicSearch, collectionName:'topics', objectName:'topic'},
{filterBox: this.StyleSearch, collectionName:'styles', objectName:'style'}
]);
var collectionName:String;
var objectName:String;
switch(filter){
case 'category':
//search for the different categories in the content and return a dataProvider
collectionName = "categories";
objectName = "category";
break;
case 'brand':
collectionName = "brands";
objectName = "brand";
break;
case 'topic':
collectionName = "topics";
objectName = "topic";
break;
case 'style':
collectionName = "styles";
objectName = "style";
break;
}
//
var node:*;
var len:Number = content.length;
for(var i:Number = 0;i<len;i++){ //content.length
var found:Boolean = false;
try{
if(isDetails == true){
node = content[i]["poidetails"][collectionName][objectName];
}else{
node = content[i][collectionName][objectName];
}
if(node is ArrayCollection){
tryAddingCollection(node, returnProvider);
}else{
//check for duplicates else add them
tryAddingProxy(node, returnProvider);
}
}catch(error:Error){
}
}
var dataSortField:SortField = new SortField();
dataSortField.name = "name";
dataSortField.descending = false;
dataSortField.caseInsensitive = true;
/* Create the Sort object and add the SortField object created earlier to the array of fields to sort on. */
var DataSort:Sort = new Sort();
DataSort.fields = [dataSortField];
/* Set the ArrayCollection object's sort property to our custom sort, and refresh the ArrayCollection. */
returnProvider.sort = DataSort;
returnProvider.refresh();
return returnProvider;
}
private function tryAddingCollection(node:ArrayCollection, returnProvider:ArrayCollection):void{
for(var c:Number = 0;c<node.length;c++){
//check for duplicates else add them (if they belong to other filters)
/*var found:Boolean = false;
for(var d:Number = 0; d<returnProvider.length;d++){
if(returnProvider[d].id == node[c].id){
found = true;
}
}*/
//if(!found){
var _variable:String = makeCorrectVariable(node[c])
if(relevantFilterData[_variable] == null){
returnProvider.addItem(node[c]);
relevantFilterData[_variable] = 1;
}
//}
}
}
private function tryAddingProxy(node:Object, returnProvider:ArrayCollection):void{
/*var found:Boolean = false;
for(var d:Number = 0; d<returnProvider.length;d++){
if(returnProvider[d].id == node.id){
found = true;
}
}
if(!found){
*/
var _variable:String = makeCorrectVariable(node)
if(relevantFilterData[_variable] == null){
returnProvider.addItem(node);
relevantFilterData[_variable] = 1;
}
//}
}
Een hele brok ik weet het maar deze filters gelden voor 3 modules (blog, hopping en video). En dienen als rode draad door de navigatie.
Het is bovendien vrij oude code die ik in het begin van de site geschreven heb en besef dat dit niet echt mooie code is
Zelf start ik met een kleine hang die ik aan het begin van mijn applicatie heb.
Dit omdat de functie vele for loops bevat die zoeken in objecten. Ik heb de functie opgesplitst in kleinere functies en de for loops getyped als Number
for(var i:Number = 0;i<data.length;i++)
Zijn er nog tips of zaken die ik kan proberen om die hang te voorkomen? Site mag iets langer laden zolang die maar niet blijft hangen.
Voor wie geinteresseerd is in de code (die herschreven moet worden vanaf nul binnenkort, ik weet het! :) )
public function createSearchProvider(module:String):void{
relevantFilterData = new Object();
//create the provider for filters and search box
if(availableFilters.length < 1){
availableFilters = new ArrayCollection([
{filterBox:this.CategorySearch, filterContainer:'categories', filterName:'category'},
{filterBox:this.BrandSearch, filterContainer:'brands', filterName:'brand'},
{filterBox:this.TopicSearch, filterContainer:'topics', filterName:'topic'},
{filterBox:this.StyleSearch, filterContainer:'styles', filterName:'style'}
]);
}
// var modules:Array = new Array("video","hopping","blog");
var moduleObject:Object = this[module+"Data"];
//set up the search data for each module (search in title/name, description/content, address, phoneNumber, brands, styles, topics, categories
moduleObject.moduleName = module;
moduleObject.brandProvider = getRelevantFilterData("brand",module);
moduleObject.categoryProvider = getRelevantFilterData("category",module);
moduleObject.styleProvider = getRelevantFilterData("style",module);
moduleObject.topicProvider = getRelevantFilterData("topic",module);
this.callLater(setupProvider,[module]);
}
private function setupProvider(module:String):void{
for(var a:Number = 0;a<availableFilters.length;a++){
var filter:Object = availableFilters[a];
determineSearchProvider(filter, module);
}
}
public function determineSearchProvider(filter:Object, module:String):void{
//To optimize search speed we already assign an array of id's to a filter where the item contains this filtervalue
var content:ArrayCollection;
var node:*;
switch(module){
case 'video':
content = this.parentDocument.videos;
break;
case 'hopping':
content = this.parentDocument.pois;
break;
case 'blog':
content = this.parentDocument.blogitems;
break;
}
for(var p:Number = 0;p<content.length;p++){
//for every item check if it matches the filters contents
var _check:Boolean = true;
switch(module){
case 'video':
try{
node = content[p][filter.filterContainer][filter.filterName];
}catch(err:Error){
var _check:Boolean = false;
}
break;
case 'hopping':
try{
node = content[p].poidetails[filter.filterContainer][filter.filterName];
}catch(err:Error){
var _check:Boolean = false;
}
break;
case 'blog':
try{
node = content[p][filter.filterContainer][filter.filterName];
}catch(err:Error){
var _check:Boolean = false;
}
break;
}
var filterValues:ArrayCollection = this[module+"Data"][filter.filterName+"Provider"];
for(var c:Number = 0; c<filterValues.length;c++){ //resultaat is bvb Kleding
if(_check){
//var _collection:* = node;
if(node is ArrayCollection){
for(var f:Number = 0;f<node.length;f++){
if(node[f].name.toLowerCase() == filterValues[c].name.toLowerCase()){
//this.parentDocument.debug.text += pois[p].poidetails.name + " behoort tot de " + filter.filterName + " " + hoppingData[filter.filterName+"Provider"][c].name + "\n";
//een filter(bvb category(kleding)) komt overeen met een filter uit de poi (kleding == kleding)
//dus moeten we kijken of deze winkel al eens is toegevoegd en anders dit id toevoegen aan de relevantKleding arrayCollection(id, module, matchType)
//als de relevant array nog niet bestaat maken we deze aan
if(this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()] == null){
this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()] = new ArrayCollection();
//add the new id to the arraycollection
var obj:Object = new Object;
obj.id = content[p].id;
obj.matchType = filter.filterName;
obj.module = module;
this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()].addItem(obj);
}else{
var found:Boolean = false;
for(var r:Number = 0;r<this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()].length;r++){
if(this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()][r] == content[p].id){
//Alert.show(pois[p].poidetails.name + "heeft meerdere ... ? en zit al in de array");
found = true;
}
}
if(!found){
//add the new id to the arraycollection
var obj:Object = new Object;
obj.id = content[p].id;
obj.matchType = filter.filterName;
obj.module = module;
this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()].addItem(obj);
}
}
}
}//end for
}else{
if(node.name.toLowerCase() == filterValues[c].name.toLowerCase()){
//this.parentDocument.debug.text += pois[p].poidetails.name + " behoort tot de " + filter.filterName + " " + hoppingData[filter.filterName+"Provider"][c].name + "\n";
//een filter(bvb category(kleding)) komt overeen met een filter uit de poi (kleding == kleding)
//dus moeten we kijken of deze winkel al eens is toegevoegd en anders dit id toevoegen aan de relevantKleding arrayCollection(id, module, matchType)
//als de relevant array nog niet bestaat maken we deze aan
if(this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()] == null){
this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()] = new ArrayCollection();
//add the new id to the arraycollection
var obj:Object = new Object;
obj.id = content[p].id;
obj.matchType = filter.filterName;
obj.module = module;
this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()].addItem(obj);
}else{
var found:Boolean = false;
for(var r:Number = 0;r<this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()].length;r++){
if(this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()][r] == content[p].id){
found = true;
}
}
if(!found){
//add the new id to the arraycollection
var obj:Object = new Object;
obj.id = content[p].id;
obj.matchType = filter.filterName;
obj.module = module;
this[module+"Data"]["relevant_" + filterValues[c].name.toLowerCase()].addItem(obj);
}
}
}
}
}else{
//node is niet bruikbaar(ingevuld)
}
}
}
}
//this function determines which categories are in the dataProvider of the content and returns a dataProvider for the filterMenu
public var relevantFilterData:Object = new Object;
private function getRelevantFilterData(filter:String, moduleName:String = null):ArrayCollection{
if(moduleName == null){
moduleName = Application.application.moduleName;
}
//and set the one we return
var returnProvider:ArrayCollection = new ArrayCollection;
var content:ArrayCollection;
var isDetails:Boolean = false;
switch(moduleName){
case 'video':
content = this.parentDocument.videos;
break;
case 'hopping':
content = this.parentDocument.pois;
isDetails = true;
break;
case 'blog':
content = this.parentDocument.blogitems;
break;
}
content.filterFunction = null;
content.refresh();
returnProvider = returnCollectionForMenuFilter(content, filter, isDetails);
return returnProvider;
}
private function returnCollectionForMenuFilter(content:ArrayCollect ion, filter:String, isDetails:Boolean = false):ArrayCollection{
//determine which content we use
var returnProvider:ArrayCollection = new ArrayCollection;
var possibleFilters:ArrayCollection = new ArrayCollection([
{filterBox: this.CategorySearch, collectionName:'categories', objectName:'category'},
{filterBox: this.BrandSearch, collectionName:'brands', objectName:'brand'},
{filterBox: this.TopicSearch, collectionName:'topics', objectName:'topic'},
{filterBox: this.StyleSearch, collectionName:'styles', objectName:'style'}
]);
var collectionName:String;
var objectName:String;
switch(filter){
case 'category':
//search for the different categories in the content and return a dataProvider
collectionName = "categories";
objectName = "category";
break;
case 'brand':
collectionName = "brands";
objectName = "brand";
break;
case 'topic':
collectionName = "topics";
objectName = "topic";
break;
case 'style':
collectionName = "styles";
objectName = "style";
break;
}
//
var node:*;
var len:Number = content.length;
for(var i:Number = 0;i<len;i++){ //content.length
var found:Boolean = false;
try{
if(isDetails == true){
node = content[i]["poidetails"][collectionName][objectName];
}else{
node = content[i][collectionName][objectName];
}
if(node is ArrayCollection){
tryAddingCollection(node, returnProvider);
}else{
//check for duplicates else add them
tryAddingProxy(node, returnProvider);
}
}catch(error:Error){
}
}
var dataSortField:SortField = new SortField();
dataSortField.name = "name";
dataSortField.descending = false;
dataSortField.caseInsensitive = true;
/* Create the Sort object and add the SortField object created earlier to the array of fields to sort on. */
var DataSort:Sort = new Sort();
DataSort.fields = [dataSortField];
/* Set the ArrayCollection object's sort property to our custom sort, and refresh the ArrayCollection. */
returnProvider.sort = DataSort;
returnProvider.refresh();
return returnProvider;
}
private function tryAddingCollection(node:ArrayCollection, returnProvider:ArrayCollection):void{
for(var c:Number = 0;c<node.length;c++){
//check for duplicates else add them (if they belong to other filters)
/*var found:Boolean = false;
for(var d:Number = 0; d<returnProvider.length;d++){
if(returnProvider[d].id == node[c].id){
found = true;
}
}*/
//if(!found){
var _variable:String = makeCorrectVariable(node[c])
if(relevantFilterData[_variable] == null){
returnProvider.addItem(node[c]);
relevantFilterData[_variable] = 1;
}
//}
}
}
private function tryAddingProxy(node:Object, returnProvider:ArrayCollection):void{
/*var found:Boolean = false;
for(var d:Number = 0; d<returnProvider.length;d++){
if(returnProvider[d].id == node.id){
found = true;
}
}
if(!found){
*/
var _variable:String = makeCorrectVariable(node)
if(relevantFilterData[_variable] == null){
returnProvider.addItem(node);
relevantFilterData[_variable] = 1;
}
//}
}
Een hele brok ik weet het maar deze filters gelden voor 3 modules (blog, hopping en video). En dienen als rode draad door de navigatie.
Het is bovendien vrij oude code die ik in het begin van de site geschreven heb en besef dat dit niet echt mooie code is