Skip to main content

What You’ll Learn

By the end of this guide, you’ll understand:
  • ✅ How to build indexes for fast searching in large datasets
  • ✅ When to use indexes vs. direct traversal
  • ✅ How to recognize and handle detached objects
  • ✅ How to access nested Revit parameters efficiently

Prerequisites

Before starting this guide, you should:
  • Understand how to traverse and filter objects
  • Be comfortable with Python data structures (dictionaries, sets)
  • Have worked with real-world Speckle projects (1000+ objects)
This guide focuses on performance optimization and complex patterns for working with large BIM datasets. These patterns are most useful when dealing with projects from connectors like Revit, Rhino, or ArchiCAD.

How do I make searching faster with indexes?

Repeatedly traversing large object trees is slow. If you need to search for multiple categories or properties, traversing the entire tree each time becomes a performance bottleneck.
Terminology Note: Examples use property names like “category”, “level”, etc. for illustration. Real BIM data from connectors may structure these differently - Revit uses both direct properties AND proxy collections (e.g., LevelProxy, CategoryProxy). See BIM Data Patterns for connector-specific structures.
Build an index once, then perform fast lookups using GraphTraversal:
Indexing pattern: (1) Traverse once - Visit every object in the tree, (2) Extract key - Get the property value to index by (e.g., category), (3) Store reference - Add object to a dictionary by that key, (4) Fast lookup - Use dictionary access (O(1)) instead of tree traversal (O(n)). Performance comparison:
Multi-property index - index by multiple properties for complex queries using GraphTraversal:
ID-based index - build indexes by object IDs for fast lookups using GraphTraversal:
Don’t rebuild indexes unnecessarily! Building an index is expensive (O(n)). Cache the index and reuse it:

When should I use indexes vs. direct traversal?

You need to decide whether to traverse directly or build an index first. The wrong choice can hurt performance. Use direct traversal when:
  • ✅ Single search on a dataset
  • ✅ Small datasets (less than 100 objects)
  • ✅ One-time operation
  • ✅ Memory is very limited
Use indexes when:
  • ✅ Multiple searches on the same dataset
  • ✅ Large datasets (1000+ objects)
  • ✅ Repeated lookups by the same property
  • ✅ Performance is critical
Performance example:

How do I handle detached objects?

Some objects in Speckle are “detached” - stored separately and referenced by ID. You see properties like @displayValue instead of the actual object. Understand when and why detachment happens:
Why detachment happens: (1) Performance - Large objects (big meshes) are stored separately, (2) Deduplication - Same object can be referenced multiple times, (3) Lazy loading - Objects loaded only when needed. How it’s resolved:
Checking for detached properties:
Don’t assume all properties are resolved! In rare cases with custom transports or partial receives, references might not be resolved:

How do I access Revit parameters efficiently?

Revit objects have complex nested parameter structures organized by category. Accessing them efficiently requires understanding this structure. Access parameters via the properties dictionary:
Understanding Revit parameter structure:
Extracting all parameters:
Building a parameter index using GraphTraversal:

Practical Examples

Example 1: Complete Analysis Pipeline

Example 2: Export to DataFrame

Learn More

Core Concepts: Guides: API Reference:

Summary

You’ve now learned:
  • Build indexes for O(1) lookups instead of O(n) traversals
  • Choose wisely between direct traversal and indexing
  • Handle detached objects and understand when they occur
  • Access Revit parameters efficiently through the properties structure
These patterns will help you work efficiently with large, complex BIM datasets in SpecklePy.
Last modified on July 18, 2026