From 96ebd50adffbee1fb1d54aca66617d639d984e09 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Mon, 10 Aug 2026 20:43:17 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20=EB=B0=B0=EC=97=B4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=8B=9C=20=EC=A4=91=EA=B0=84=20ArrayList?= =?UTF-8?q?=20=ED=95=A0=EB=8B=B9=20=EC=A0=9C=EA=B1=B0=20(Avoid=20intermedi?= =?UTF-8?q?ate=20ArrayList=20allocation)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kotlin에서 `Collection.map { ... }.toTypedArray()`를 사용하면 중간에 불필요한 `ArrayList`가 생성되어 가비지 컬렉션(GC) 및 메모리 할당 오버헤드가 발생합니다. 핫 패스에서는 이로 인한 성능 저하가 큽니다. 이를 해결하기 위해 `Array(size) { index -> ... }` 생성자를 직접 사용하여 배열을 직접 초기화하여 성능을 개선했습니다. --- .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..b38d7a4 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-24 - 배열 생성 시 중간 리스트 할당 회피 +**학습:** Kotlin에서 `Collection.map { ... }.toTypedArray()`를 사용하면 중간에 불필요한 `ArrayList`가 생성되어 가비지 컬렉션(GC) 및 메모리 할당 오버헤드가 발생합니다. 핫 패스에서는 이로 인한 성능 저하가 큽니다. +**조치:** 핫 패스에서 배열을 생성할 때는 중간 리스트 생성을 피하기 위해 `Array(size) { index -> ... }` 생성자를 직접 사용하여 직접 초기화합니다. diff --git a/src/main/kotlin/html4tree/main.kt b/src/main/kotlin/html4tree/main.kt index 8942c04..c8cbcb4 100644 --- a/src/main/kotlin/html4tree/main.kt +++ b/src/main/kotlin/html4tree/main.kt @@ -172,7 +172,8 @@ internal fun crawl_directories( // ⚡ Bolt Performance Optimization: 디렉토리 목록을 캐싱하여 중복된 I/O 시스템 호출을 줄임 val dirFiles = listFiles(lle.file) - val dirFilesNames = dirFiles?.map { it.name }?.toTypedArray() + // ⚡ Bolt Performance Optimization: Avoid intermediate ArrayList allocation during array creation + val dirFilesNames = dirFiles?.let { files -> Array(files.size) { files[it].name } } val exclude = processIgnoreFile(lle.file, dirFilesNames) if(maxLevel == -1 || currentLevel <= maxLevel)