Performance Overview
We’ve optimized XIRR calculations from ~385ms to ~3-5ms per calculation (100-150x improvement). In real-world queries with multiple entities, we’ve seen improvements up to 700x faster (23 seconds → 32ms).Available Implementations
| Implementation | Exception Handling | Parallel-Safe | Speed | Use Case |
|---|---|---|---|---|
xirr_agg | Full | No | ~385ms | Debugging, edge cases |
xirr_safe_fast_agg | Returns NULL | No | ~3-5ms | Production (recommended) |
xirr_fast_agg | Raises errors | No | ~3-5ms | Development/debugging |
Quick Start
For production use:Key Optimizations
1. Data Type Change: NUMERIC → DOUBLE PRECISION
Hardware acceleration for floating-point math provides orders of magnitude faster mathematical operations.2. Algorithm Improvements
- Pre-compute year offsets once instead of repeatedly
- Vectorized NPV calculation using SQL aggregates
- Smart initial guess based on total positive/negative flows
- Early exit for impossible cases
3. Exception Handling Trade-offs
- Original: EXCEPTION blocks prevent parallel execution
- Production: Balanced approach with error details
File Reference
Files are located inbackend/server/apps/calculations/sql/:
| File | Description |
|---|---|
xirr_original.sql | Baseline implementation using NUMERIC type |
xirr_production.sql | Recommended production implementation |
benchmark_xirr.sql | Performance testing suite |
recreate_xirr.sh | Drop and recreate all implementations |
Parallel Processing
We tested parallel XIRR aggregation but removed it after benchmarking showed only modest improvements:| Dataset Size | Performance Change |
|---|---|
| Small (1K rows) | 12% slower (overhead) |
| Medium (20K rows) | 13% faster |
| Large (300K rows) | 28% faster |
Re-enabling Parallel Processing
If needed for very large datasets:- Add COMBINEFUNC to enable true parallelism:
- Remove EXCEPTION blocks from the main function
- Update aggregate definition with
COMBINEFUNCandPARALLEL = SAFE - Configure PostgreSQL:
Known Limitations
- Extreme Date Ranges: Production version validates date ranges to be within 100 years
- Precision Differences: DOUBLE PRECISION may show slight differences from NUMERIC in edge cases
- Convergence: Some extreme returns may not converge (matching Excel #NUM! behavior)
Running Benchmarks
Development Guidelines
Creating New Implementations
- Create as a standalone file (e.g.,
xirr_gpu_accelerated.sql) - Include all components: functions, types, aggregates in one file
- Test thoroughly using
benchmark_xirr.sqlas a template - Document what makes this implementation unique
Modifying Existing Implementations
- Create versioned copy: Copy original to
_v2(e.g.,xirr_production_v2.sql) - Make changes in the v2 file: Keep original intact for comparison
- Test the v2 implementation:
- Benchmark against original: Ensure improvements and no regressions
- Once verified, merge back:
- Replace content in original file
- Delete the v2 file
- Update
recreate_xirr.shif function signatures changed