diff --git a/.jules/bolt.md b/.jules/bolt.md index ee124e69..37510ffe 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -62,3 +62,6 @@ ## 2026-08-11 - Array의 toMutableList 할당 오버헤드 최적화 **학습:** 배열을 정렬하기 위해 `.toMutableList()`를 호출하면 새로운 `ArrayList` 객체와 내부 배열 객체가 할당되어 대규모 디렉토리를 순회할 때 가비지 컬렉션(GC) 부하를 유발합니다. 배열 복제가 필요한 경우 `.clone()`을 사용하면 하나의 배열 객체만 새로 할당되므로 더 효율적입니다. **조치:** 디렉토리 파일 배열을 정렬하기 전에 복사할 때 `.toMutableList()` 대신 `.clone()`을 사용하여 불필요한 중간 컬렉션 할당을 제거하고 성능을 향상시켰습니다. +## 2026-08-11 - 불필요한 객체 할당(toLowerCase) 지연 +**학습:** 디렉토리 크롤러와 같은 핫 패스 루프 내에서, 필터링 조건을 평가하기 위해 `toLowerCase()` 등 문자열 복사/할당을 먼저 수행하는 것은 심각한 가비지 컬렉션(GC) 부하를 유발합니다. 객체 할당 없이 빠르게 평가할 수 있는 조건(`isHiddenFile()`, `endsWith()`)을 먼저 평가하여 short-circuit 되도록 최적화해야 합니다. +**조치:** 불필요한 객체 할당 및 연산을 피하기 위해 비용이 많이 드는 연산(`toLowerCase()`)은 그 값이 진짜로 필요한 논리 분기 안으로 지연(defer)시키고 싼 조건 검사를 먼저 수행하도록 조건문을 재배열했습니다. diff --git a/src/main/kotlin/html4tree/main.kt b/src/main/kotlin/html4tree/main.kt index 0972fa2c..76d2cb50 100644 --- a/src/main/kotlin/html4tree/main.kt +++ b/src/main/kotlin/html4tree/main.kt @@ -350,17 +350,21 @@ fun process_ignore_file(curr_dir: File, dirFilesNames: Array? = null): S files_to_exclude.addAll(Constants.defaultSensitiveFiles) // 보안 향상: dot-like prefixes and case variants of known sensitive names are excluded. + // ⚡ Bolt Performance Optimization: Defer expensive string allocations (toLowerCase) + // by evaluating cheap, short-circuiting properties (isHiddenFile, endsWith) first. (dirFilesNames ?: curr_dir.list())?.forEach { - val normalizedName = it.toLowerCase(java.util.Locale.ROOT) - if ( - it.isHiddenFile() || - normalizedName in Constants.defaultSensitiveFileNamesLowercase || - normalizedName.endsWith("~") || - Constants.defaultSensitiveExtensions.any { extension -> - normalizedName.endsWith(extension) - } - ) { + if (it.isHiddenFile() || it.endsWith("~")) { files_to_exclude.add(it) + } else { + val normalizedName = it.toLowerCase(java.util.Locale.ROOT) + if ( + normalizedName in Constants.defaultSensitiveFileNamesLowercase || + Constants.defaultSensitiveExtensions.any { extension -> + normalizedName.endsWith(extension) + } + ) { + files_to_exclude.add(it) + } } }