From f36ddd7183a2c44b7e327c8a673c0c99a6ec6d22 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Mon, 10 Aug 2026 03:47:32 +0000 Subject: [PATCH] =?UTF-8?q?=EC=A0=95=EB=A0=AC=EC=97=90=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EB=90=98=EB=8A=94=20Comparator=EB=A5=BC=20=EC=B5=9C?= =?UTF-8?q?=EC=83=81=EC=9C=84=20=EB=A0=88=EB=B2=A8=EB=A1=9C=20=ED=98=B8?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=ED=8C=85=ED=95=98=EC=97=AC=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20=ED=95=A0=EB=8B=B9=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .jules/bolt.md | 3 +++ src/main/kotlin/html4tree/main.kt | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 165882d..be7eab1 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -46,3 +46,6 @@ ## 2025-01-24 - 단일 readAttributes 호출로 파일 속성 조회 최적화 (순회 루프) **학습:** 디렉토리 순회 루프 내에서 isDirectory 및 isSymbolicLink 두 번의 stat을 각각 호출하면 파일 시스템 I/O 오버헤드가 배가됩니다. 메모리 내 제외 규칙 확인 후 한 번의 readAttributes로 속성을 한 번에 가져오는 것이 훨씬 빠릅니다. **조치:** Files.isDirectory 및 Files.isSymbolicLink를 단일 Files.readAttributes 호출로 교체하여 O(N) I/O 통신을 최적화했습니다. +## 2025-01-25 - Comparator 객체 생성 방지 (루프 외부 할당) +**학습:** Kotlin에서 `compareBy { it.name }`를 루프 내부에서 또는 빈번하게 호출되는 함수에서 사용할 경우 매 호출마다 새로운 `Comparator` 객체가 할당되어 성능 및 가비지 컬렉션(GC) 압력이 발생합니다. +**조치:** 빈번한 정렬 작업에 사용되는 Comparator를 최상위 레벨의 `private val` 상수로 호이스팅(hoisting)하여 매번 새롭게 객체가 생성되는 것을 방지합니다. diff --git a/src/main/kotlin/html4tree/main.kt b/src/main/kotlin/html4tree/main.kt index 8942c04..6920638 100644 --- a/src/main/kotlin/html4tree/main.kt +++ b/src/main/kotlin/html4tree/main.kt @@ -94,6 +94,7 @@ li + li { """.trimIndent() private val STYLE_HASH = "sha256-" + Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-256").digest(CSS_CONTENT.toByteArray(Charsets.UTF_8))) +private val FILE_NAME_COMPARATOR = compareBy { it.name } class Html4tree : CliktCommand() { val maxLevel:Int by option(help="Number of levels deep for which to generate an index.html file", hidden = false).int().default(-1) @@ -368,7 +369,7 @@ fun process_dir(curr_dir: File, excludeSet: Set? = null, dirFiles: Array val filesList = dirFiles ?: curr_dir.listFiles() val dir_files: MutableList = filesList?.toMutableList() ?: mutableListOf() - dir_files.sortWith(compareBy ({it.name}) ) + dir_files.sortWith(FILE_NAME_COMPARATOR) dir_files.forEach { val fileName = it.getName() // ⚡ Bolt Performance Optimization: Short-circuit string match before expensive OS filesystem calls