Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Quickly Filtering the elements based on a custom parameter value.

Message 1 of 4
1834 Views, 3 Replies

Quickly Filtering the elements based on a custom parameter value.

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?


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


Message 2 of 4
in reply to: Anonymous

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:


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


I hope this helps.






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

Message 3 of 4
in reply to: jeremytammik

@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);


Message 4 of 4
in reply to: Anonymous



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

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Customer Advisory Groups

Rail Community