Quickly Filtering the elements based on a custom parameter value.

Quickly Filtering the elements based on a custom parameter value.

Anonymous
Not applicable
2,558 Views
3 Replies
Message 1 of 4

Quickly Filtering the elements based on a custom parameter value.

Anonymous
Not applicable

Hi All,

LightElementList has all the Light Fixture Elements used in the project(400+) and AllItems is a list of Item Class (500+ ) where each item has a property called "FamilySKU".
What I am trying to do is drop elements from LightElementList whose "SKU" parameter value is not found in AllItems. I am able to do that with the following code, but that one single line takes 27sec to finish. 

Is there a way to accomplish this in the least amount of time?
Thanks

 

lightElementsList.RemoveAll(e => AllItems.FirstOrDefault(x => x.FamilySKU == (e as FamilyInstance).Symbol.LookupParameter("SKU").AsString()) == null); 

 

0 Likes
Accepted solutions (1)
2,559 Views
3 Replies
Replies (3)
Message 2 of 4

jeremytammik
Autodesk
Autodesk
Accepted solution

Nice question.

 

Yes, there is. 

 

Several steps in your code are inefficient.

 

Oh dear, the most efficient approach of all is already impossible in the situation you show.

 

You could perform the filtering you describe using the Revit API filtered element collector.

 

That would avoid marshalling to transfer all the (unneeded and unwanted) element data out of the Revit memory space into your .NET add-in memory.

 

Unfortunately, the code snippet you share is already past that stage.

 

Still, that can also be vastly improved:

 

LookupParameter is very inefficient.

 

Determine the id of the Definition of the SKU parameter that you are interested in, say, id_sku.

 

Then, instead of LookupParameter, use get_Parameter(id_sku).

 

Furthermore, using AllItems.FirstOrDefault over and over hundreds of times is also very inefficient.

 

If you need to look things up, use a lookup table, aka as a dictionary.

 

Best of all, however, would be to set up a Revit API parameter filter and check the SKU parameter inside of that before retrieving all the element data to .NET at all.

   

Lots of filtering examples are provided in The Building Coder CmdCollectorPerformance.cs module:

 

https://github.com/jeremytammik/the_building_coder_samples

  

All the examples are discussed either here in the forum or in the blog.

 

I hope this helps.

 

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 3 of 4

Anonymous
Not applicable

@jeremytammik Thanks, it worked. Just by avoiding lookup parameter I was able to bring it down to 2 seconds. I guess getting rid of FirstOrDefault can optimize it even better.

For those with the similar issue, the modified code can help. I fetched the GUID as Jeremy suggested and used it to get the parameter value from the symbol.

//Fetched the GUID of the parameter I needed
Guid param_id = (lightElementsInProjectList[0] as FamilyInstance).Symbol.LookupParameter("SKU").GUID; 

//Used the GUID to get the value
lightElementsInProjectList.FindAll(e => AllItems.FirstOrDefault(x => x.FamilySku == (e as FamilyInstance).Symbol.get_Parameter(param_id).AsString()) == null);

 

0 Likes
Message 4 of 4

jeremytammik
Autodesk
Autodesk

Wow!

 

Congratulations on the huge improvement, and congratulations for making use of the tip!

 

That is very gratifying indeed.

 

It sometimes feels as if 99 out 100 suggestions I make fall on deaf ears.

 

Your ears were wide open!

 

Thank you for that, and your kind appreciation!

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder