You could probably achieve a decent performance increase by reducing the number of times you call hide / unhide / setVisibility. Specifically, the first part of the code where it hides and then unhides elements by category seems redundant.
I've used code similar to the following to do this sort of thing.
Code:
// Get the selected elements
var selectedElements = myDocument.Selection.Elements.Cast<Element>().ToArray();
// Use a collector for this particular view
using (FilteredElementCollector collector = new FilteredElementCollector(myDocument, myView.Id))
{
// Get all elements in the view excluding the selected elements
var elementsToHide = collector
.WhereElementIsNotElementType()
.Excluding(selectedElements.Select(e => e.Id).ToArray())
.ToElements();
// Populate an ElementSet with the elements to be hidden
using (var elementSet = new ElementSet())
{
foreach (var element in elementsToHide)
{
if (element.CanBeHidden(myView) && !element.IsHidden(myView))
{
elementSet.Insert(element);
}
}
// Hide the elements
myView.Hide(elementSet);
}
}
Note that you may need to consider relationships between elements. For example, in my case I was trying to isolate a hosted element and the hosted element was automatically hidden with it's host. In this case I excluded the host from the ElementSet being hidden, and then called myView.setVisibility(hostElement.Category, false) to hide the host without hiding it's hosted elements.