Skip to content

Rules Overview

Algorilla ships with 28 built-in rules that detect common algorithmic complexity anti-patterns, organized in six categories.

Loop amplifiers

Expensive operations hidden inside loop bodies that multiply the cost per iteration.

Rule Impact
Nested Lookup Linear search in a loop → quadratic cost. Fix: use a Set
Repeated Linear Scan Same collection scanned multiple times → combine into one pass
Repeated Regex in Loop Regex compiled every iteration → compile once before the loop
Regex Recompilation in Loop Regex literal recompiled per call → hoist to a constant
Expensive Serialization in Loop Serializer created per iteration → reuse a single instance
Sequential Async Join in Loop Awaits one-by-one in a loop → launch all, await together
In-Loop Collection Building Collection copied every iteration → build once outside the loop
String Concat in Loop String copied every iteration → use StringBuilder
Quadratic Removal Removing from middle of a list shifts all elements → use an iterator or filter
Repeated Reflection in Loop Reflection lookup per iteration → cache the Method/Field
Hidden Nested Loop Method call hides a nested loop → O(n²) invisible at call site
IO In Loop Network/DB/file call per iteration → batch or parallelize
Expensive Callback Expensive operation inside a callback (filter, map, sort)
Cardinality Explosion Cross-product output grows as O(n×m)

Sort abuse

Wasteful sort operations or expensive work inside sort comparators.

Rule Impact
Sort for Last Sorting entire collection just to get min/max → use min()/max()
Expensive Sort Comparator Expensive computation inside comparator runs O(n log n) times → precompute
Filter After Sort Sort runs before filter → filter first, sort fewer elements

Query patterns

Database and service call patterns that cause excessive I/O.

Rule Impact
N+1 Query DB query per item in a loop → single bulk query
Bulk Load for Single Lookup Loads all records to find one → query for just the one
Lazy Loading In Loop ORM lazy-loads per iteration → eager fetch or batch

Construction cost

Unnecessary object creation overhead.

Rule Impact
Expensive Construction Heavyweight object created per iteration → reuse a single instance

Redundancy

Repeated computations that could be cached.

Rule Impact
Redundant Expensive Call Same expensive call made multiple times → cache in a local variable
Uncached Getter Same getter called repeatedly → cache the result
Chained Getters Deep getter chain traversed multiple times → flatten or cache
Unmemoized Recursion Recursive function recomputes same inputs → add memoization
Repeated Collection Iteration Same collection iterated multiple times → combine into one pass
Loop-Invariant Hoisting Same call repeated every iteration with same result → hoist before the loop

Concurrency

Patterns that undermine parallel execution performance.

Rule Impact
Parallel Pipeline Bottleneck Synchronization bottleneck in parallel pipeline

Disabling Rules

In .algorilla.yml:

rules:
  expensive-sort-comparator:
    enabled: false

Or suppress inline:

// algorilla:ignore nested-lookup
for (Order order : orders) {
    if (discountedProductIds.contains(order.getProductId())) { ... }
}

Have questions about how rules work, what the confidence levels mean, or how Algorilla compares to other tools? Check the FAQ.