diff --git a/.jules/bolt.md b/.jules/bolt.md index 8ce7ce8f7..6087ff49f 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -77,3 +77,7 @@ ## 2024-11-20 - Optimize multiple tuple generation from a single collection **Learning:** `build_rule_metadata` derives exactly two collections, `owasp` and `cwe`, from the same references. Replacing its two generator traversals with one explicit loop reduces element visits from about 2N to N. Both versions remain O(N), so this is a constant-factor optimization rather than an asymptotic complexity improvement. **Action:** Combine repeated traversal when fixed derived collections share one source, while preserving ordering and classification semantics. Benchmark the production hot path before claiming a material wall-clock improvement. + +## 2024-11-21 - 단일 패스 최적화 +**Learning:** 여러 O(N) 리스트 컴프리헨션을 단일 O(N) 루프로 병합하면 2N에서 N으로 반복 횟수가 감소합니다. 이는 중복 순회 및 중간 할당을 방지하여 constant-factor 성능 향상을 가져옵니다. +**Action:** 이터러블 작업 시, 로컬 변수에 상태를 누적하는 단일 O(N) 패스를 사용하여 constant-factor 성능 향상을 달성하십시오. diff --git a/appguardrail_core/org_intelligence.py b/appguardrail_core/org_intelligence.py index 632179f1d..e9fdbbb5c 100644 --- a/appguardrail_core/org_intelligence.py +++ b/appguardrail_core/org_intelligence.py @@ -122,35 +122,47 @@ def build_org_inventory( active_repository_target: int = 20, ) -> OrgInventory: """Build a stable organization inventory from GitHub repo JSON.""" - repo_list = list(repos) - nonforks = [repo for repo in repo_list if not _truthy(repo.get("isFork"))] - forks = [repo for repo in repo_list if _truthy(repo.get("isFork"))] - primary_languages = Counter(_primary_language(repo) for repo in repo_list) - default_branches = Counter(_default_branch(repo) for repo in repo_list) - unsupported = sorted( - { - _primary_language(repo) - for repo in nonforks - if _primary_language(repo) not in SUPPORTED_PRIMARY_LANGUAGES - and _primary_language(repo) != "Unknown" - } - ) - supported_nonforks = sum( - 1 for repo in nonforks if _primary_language(repo) in SUPPORTED_PRIMARY_LANGUAGES - ) + # ⚡ Bolt: Consolidated multiple O(N) list comprehensions and generators into a single O(N) pass. + # This reduces loop overhead and memory allocations, providing a constant-factor speedup. + total = 0 + nonforks_count = 0 + forks_count = 0 + private_count = 0 + supported_nonforks = 0 + + primary_languages: Counter[str] = Counter() + default_branches: Counter[str] = Counter() + unsupported_set: set[str] = set() + + for repo in repos: + total += 1 + lang = _primary_language(repo) + primary_languages[lang] += 1 + default_branches[_default_branch(repo)] += 1 + + if _truthy(repo.get("isPrivate")): + private_count += 1 + + if _truthy(repo.get("isFork")): + forks_count += 1 + else: + nonforks_count += 1 + if lang in SUPPORTED_PRIMARY_LANGUAGES: + supported_nonforks += 1 + elif lang != "Unknown": + unsupported_set.add(lang) + return OrgInventory( - total_repositories=len(repo_list), - nonfork_repositories=len(nonforks), - fork_repositories=len(forks), - private_repositories=sum( - 1 for repo in repo_list if _truthy(repo.get("isPrivate")) - ), + total_repositories=total, + nonfork_repositories=nonforks_count, + fork_repositories=forks_count, + private_repositories=private_count, supported_nonfork_repositories=supported_nonforks, - unsupported_nonfork_languages=tuple(unsupported), + unsupported_nonfork_languages=tuple(sorted(unsupported_set)), primary_language_counts=_sorted_counts(primary_languages), default_branch_counts=_sorted_counts(default_branches), active_repository_target=active_repository_target, - active_repository_target_met=len(nonforks) >= active_repository_target, + active_repository_target_met=nonforks_count >= active_repository_target, )