From 5a778fb42dd3528846f6d61da90eb4780ff401a8 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 30 Jun 2026 03:26:29 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20O(N^2)=20=EB=AC=B8=EC=9E=90?= =?UTF-8?q?=EC=97=B4=20=EC=97=B0=EA=B2=B0=20=EB=B0=8F=20O(N)=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=84=B1=EB=8A=A5=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 디렉토리 처리 시 문자열 연결을 StringBuilder로 최적화하고, 제외 파일 목록을 Set으로 변경하여 검색 속도를 O(1)로 개선했습니다. --- .jules/bolt.md | 3 +++ src/main/kotlin/html4tree/main.kt | 16 ++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 39f32f6e..49e59dd5 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -1,3 +1,6 @@ ## 2024-06-21 - Regex Compilation in Loops **Learning:** In Kotlin, compiling regular expressions (`.toRegex()`) inside a loop over files is a significant O(N * M) performance bottleneck when processing ignore files (N files * M rules). **Action:** Always map string rules to compiled `Regex` objects outside of the file iteration loop (O(M) compilation) to avoid unnecessary regex re-compilations. +## 2024-06-25 - Collection Lookup Performance in Loops +**Learning:** Checking for file exclusion (`in exclude`) inside a loop iterating over directory contents can be a significant bottleneck (O(N) lookup for each file) if the `exclude` collection is a `List`. +**Action:** Always prefer using `Set` (e.g., `mutableSetOf()`) over `List` for collections used primarily for lookup/containment checks inside loops, changing the lookup from O(N) to O(1). diff --git a/src/main/kotlin/html4tree/main.kt b/src/main/kotlin/html4tree/main.kt index 5dca48bb..308207f4 100644 --- a/src/main/kotlin/html4tree/main.kt +++ b/src/main/kotlin/html4tree/main.kt @@ -54,7 +54,7 @@ fun String.urlEncodePath(): String { return java.net.URLEncoder.encode(this, "UTF-8").replace("+", "%20") } -fun process_ignore_file(curr_dir: File): List { +fun process_ignore_file(curr_dir: File): Set { val ignore_filename = ".html4ignore" @@ -62,11 +62,12 @@ fun process_ignore_file(curr_dir: File): List { val ignore_file = File(ignore_file_path) - val files_to_exclude = mutableListOf() + val files_to_exclude = mutableSetOf() if(ignore_file.exists()){ val ignored_regexes = mutableListOf() + // O(M) regex compilation outside of N files loop ignore_file.forEachLine { ignored_regexes.add(("^"+it+"$").toRegex()) } curr_dir.list().sorted().forEach { @@ -79,15 +80,14 @@ fun process_ignore_file(curr_dir: File): List { } } - if ("index.html" !in files_to_exclude) - files_to_exclude.add("index.html") + files_to_exclude.add("index.html") // Sets handle duplicates automatically, but no harm ensuring it's there return files_to_exclude } fun process_dir(curr_dir: File){ - val exclude: List = process_ignore_file(curr_dir) + val exclude: Set = process_ignore_file(curr_dir) val css = """