|
5 | 5 | from policyengine_core import periods |
6 | 6 | from policyengine_core.periods import config |
7 | 7 |
|
| 8 | +# Global cache for instant objects to avoid repeated tuple creation |
| 9 | +_instant_cache: dict = {} |
8 | 10 |
|
9 | | -@lru_cache(maxsize=1024) |
| 11 | + |
| 12 | +@lru_cache(maxsize=10000) |
10 | 13 | def _instant_from_string(instant_str: str) -> "periods.Instant": |
11 | 14 | """Cached parsing of instant strings.""" |
12 | 15 | if not config.INSTANT_PATTERN.match(instant_str): |
@@ -48,18 +51,35 @@ def instant(instant): |
48 | 51 | return instant |
49 | 52 | if isinstance(instant, str): |
50 | 53 | return _instant_from_string(instant) |
| 54 | + |
| 55 | + # For other types, create a cache key and check the cache |
| 56 | + cache_key = None |
| 57 | + # Check Period before tuple since Period is a subclass of tuple |
| 58 | + if isinstance(instant, periods.Period): |
| 59 | + return instant.start |
51 | 60 | elif isinstance(instant, datetime.date): |
52 | | - instant = periods.Instant((instant.year, instant.month, instant.day)) |
| 61 | + cache_key = (instant.year, instant.month, instant.day) |
53 | 62 | elif isinstance(instant, int): |
54 | | - instant = (instant,) |
55 | | - elif isinstance(instant, list): |
56 | | - assert 1 <= len(instant) <= 3 |
57 | | - instant = tuple(instant) |
58 | | - elif isinstance(instant, periods.Period): |
59 | | - instant = instant.start |
60 | | - else: |
61 | | - assert isinstance(instant, tuple), instant |
62 | | - assert 1 <= len(instant) <= 3 |
| 63 | + cache_key = (instant, 1, 1) |
| 64 | + elif isinstance(instant, (tuple, list)): |
| 65 | + if len(instant) == 1: |
| 66 | + cache_key = (instant[0], 1, 1) |
| 67 | + elif len(instant) == 2: |
| 68 | + cache_key = (instant[0], instant[1], 1) |
| 69 | + elif len(instant) == 3: |
| 70 | + cache_key = tuple(instant) |
| 71 | + |
| 72 | + if cache_key is not None: |
| 73 | + cached = _instant_cache.get(cache_key) |
| 74 | + if cached is not None: |
| 75 | + return cached |
| 76 | + result = periods.Instant(cache_key) |
| 77 | + _instant_cache[cache_key] = result |
| 78 | + return result |
| 79 | + |
| 80 | + # Fallback for unexpected types |
| 81 | + assert isinstance(instant, tuple), instant |
| 82 | + assert 1 <= len(instant) <= 3 |
63 | 83 | if len(instant) == 1: |
64 | 84 | return periods.Instant((instant[0], 1, 1)) |
65 | 85 | if len(instant) == 2: |
|
0 commit comments