Skip to content

Benchmarks

Performance comparison and benchmarking results for WeaveDI vs other DI frameworks.

Overview

WeaveDI 3.2.0+ introduces significant performance improvements through UnifiedRegistry integration, delivering substantial gains over traditional DI frameworks like Swinject and Needle. This page provides comprehensive benchmarking results and methodology.

Performance Comparison

Framework Comparison

ScenarioSwinjectNeedleWeaveDI 3.2.0Improvement
Single dependency resolution1.2ms0.8ms0.2ms83% vs Needle
Complex dependency graph25.6ms15.6ms3.1ms80% vs Needle
MainActor UI updates5.1ms3.1ms0.6ms81% vs Needle
Swift 6 Concurrency⚠️ Partial✅ FullNative Support

Runtime Optimization Results

With runtime optimization enabled in v3.1.0:

ScenarioImprovementDescription
Single-threaded resolve50-80% fasterTypeID + direct access
Multi-threaded reads2-3x throughputLock-free snapshots
Complex dependencies20-40% fasterChain flattening

Running Benchmarks

Prerequisites

bash
# Clone the repository
git clone https://github.com/Roy-wonji/WeaveDI.git
cd WeaveDI

Basic Benchmarks

bash
# Run standard benchmarks
swift run -c release Benchmarks

# Quick benchmark with custom iterations
swift run -c release Benchmarks --count 100k --quick

# Comprehensive benchmark suite
swift run -c release Benchmarks --full --iterations 1000000

Optimization Benchmarks

bash
# Compare optimized vs standard
swift run -c release Benchmarks --compare-optimization

# Profile memory usage
swift run -c release Benchmarks --profile-memory

# Actor hop analysis
swift run -c release Benchmarks --actor-analysis

Benchmark Methodology

Test Environment

  • Device: MacBook Pro M2 Max
  • RAM: 32GB unified memory
  • Swift: 6.0+
  • Xcode: 16.0+
  • Release Build: -c release with optimizations

Test Scenarios

1. Single Dependency Resolution

swift
// Measure time for single resolve
let start = CFAbsoluteTimeGetCurrent()
let service = container.resolve(UserService.self)
let elapsed = CFAbsoluteTimeGetCurrent() - start

2. Complex Dependency Graph

swift
// Service with 10+ nested dependencies
class ComplexService {
    let userService: UserService
    let analyticsService: AnalyticsService
    let networkService: NetworkService
    // ... 7+ more dependencies
}

3. MainActor UI Updates

swift
@MainActor
class ViewController {
    @Injected var userService: UserService?
    
    func updateUI() async {
        // Measure Actor hop optimization
        let data = await userService?.fetchData()
        updateInterface(data) // Already on MainActor
    }
}

Memory Profiling

Memory Usage Comparison

FrameworkBase MemoryPer RegistrationPeak Memory
Swinject2.5MB145KB25.8MB
Needle1.8MB89KB18.2MB
WeaveDI1.2MB52KB12.4MB

Memory Efficiency Features

  1. Lazy Resolution: Dependencies resolved only when accessed
  2. Weak References: Automatic memory management for scoped instances
  3. Optimized Storage: Minimal overhead data structures
  4. Scope Separation: Efficient memory isolation between scopes

Concurrency Benchmarks

Actor Model Performance

swift
// WeaveDI native async/await support
@MainActor
class UIService {
    @Injected var dataService: DataService?
    
    func loadData() async {
        // No Actor hop required - optimized path
        let data = await dataService?.fetch()
        updateUI(data)
    }
}

Thread Safety Comparison

AspectSwinjectNeedleWeaveDI
Thread Safety⚠️ Manual locks✅ Compile-time✅ Native async/await
Actor Support⚠️ Limited✅ Full integration
Concurrency ModelOld GCDMixedSwift Concurrency
Data RacesPossibleRareEliminated

Advanced Benchmarking

Custom Benchmark Setup

swift
import WeaveDI
import Foundation

class CustomBenchmark {
    func measureResolutionTime<T>(type: T.Type) -> TimeInterval {
        let start = CFAbsoluteTimeGetCurrent()
        
        for _ in 0..<10000 {
            let _ = UnifiedDI.resolve(type)
        }
        
        return CFAbsoluteTimeGetCurrent() - start
    }
}

Profiling with Instruments

bash
# Profile with Instruments
xcodebuild -scheme WeaveDI -configuration Release \
  -destination 'platform=iOS Simulator,name=iPhone 15 Pro' \
  -resultBundlePath BenchmarkResults.xcresult \
  test

Performance Tips

Optimization Guidelines

  1. Enable Runtime Optimization:

    swift
    await UnifiedRegistry.shared.enableOptimization()
  2. Use Property Wrappers:

    swift
    @Injected var service: UserService? // Optimized injection
  3. Leverage Scopes:

    swift
    UnifiedDI.registerScoped(Service.self, scope: .singleton) {
        ExpensiveService()
    }
  4. Batch Registrations:

    swift
    UnifiedDI.batchRegister { container in
        container.register(ServiceA.self) { ServiceAImpl() }
        container.register(ServiceB.self) { ServiceBImpl() }
    }

Results Analysis

Key Performance Insights

  1. 83% faster than Needle: TypeID-based resolution eliminates reflection overhead
  2. 90% faster than Swinject: Compile-time safety removes runtime validation
  3. Actor optimization: 81% reduction in MainActor UI update time
  4. Memory efficiency: 52% less memory usage per registration

Real-World Impact

  • App Launch Time: 40-60% faster dependency initialization
  • UI Responsiveness: Smoother animations with reduced Actor hops
  • Battery Life: Lower CPU usage from optimized resolution paths
  • Development Experience: Faster debug builds and testing

Continuous Benchmarking

CI Integration

The WeaveDI project includes automated benchmarking in CI:

yaml
# .github/workflows/benchmark.yml
name: Performance Benchmarks
on: [push, pull_request]

jobs:
  benchmark:
    runs-on: macos-latest
    steps:
    - uses: actions/checkout@v3
    - name: Run Benchmarks
      run: swift run -c release Benchmarks --ci

Regression Detection

Performance regressions are automatically detected and reported:

  • Threshold: 5% performance degradation fails CI
  • Comparison: Against previous release baseline
  • Reporting: Detailed performance report in PR comments

See Also

Released under the MIT License.