From 50e0fdde82f9515946388975e2f07332866099d0 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Thu, 24 Sep 2026 20:59:16 +0000 Subject: [PATCH 1/8] =?UTF-8?q?=E2=9A=A1=20Bolt:=20[=EB=A3=A8=ED=94=84=20?= =?UTF-8?q?=EB=82=B4=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=B5=9C=EC=A0=81=ED=99=94]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 복잡한 템플릿 문자열 보간을 `StringBuilder` 체이닝으로 교체 - 루프 핫 패스에서 중간 객체 할당 및 가비지 컬렉션 부하 감소 - 불필요한 중복 `escapeHtml()` 호출 제거 --- .jules/bolt.md | 4 ++++ src/main/kotlin/html4tree/main.kt | 22 ++++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index ee124e69..b9368cb3 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -62,3 +62,7 @@ ## 2026-08-11 - Array의 toMutableList 할당 오버헤드 최적화 **학습:** 배열을 정렬하기 위해 `.toMutableList()`를 호출하면 새로운 `ArrayList` 객체와 내부 배열 객체가 할당되어 대규모 디렉토리를 순회할 때 가비지 컬렉션(GC) 부하를 유발합니다. 배열 복제가 필요한 경우 `.clone()`을 사용하면 하나의 배열 객체만 새로 할당되므로 더 효율적입니다. **조치:** 디렉토리 파일 배열을 정렬하기 전에 복사할 때 `.toMutableList()` 대신 `.clone()`을 사용하여 불필요한 중간 컬렉션 할당을 제거하고 성능을 향상시켰습니다. + +## 2024-09-24 - 루프 내 템플릿 문자열 보간 오버헤드 최적화 +**Learning:** 핫 패스 루프 내에서 복잡한 문자열 보간(string interpolation)과 중복된 변환(`escapeHtml()` 등)을 사용하면 불필요한 중간 객체가 생성되어 가비지 컬렉션 부하를 유발하고 성능이 저하됩니다. +**Action:** 루프 내에서 문자열을 구성할 때는 여러 번의 할당을 발생시키는 문자열 보간 대신, 이미 존재하는 `StringBuilder` 인스턴스에 직접 `.append()`를 체이닝하여 오버헤드를 줄입니다. diff --git a/src/main/kotlin/html4tree/main.kt b/src/main/kotlin/html4tree/main.kt index 0972fa2c..d34f33a5 100644 --- a/src/main/kotlin/html4tree/main.kt +++ b/src/main/kotlin/html4tree/main.kt @@ -456,12 +456,22 @@ fun process_dir(curr_dir: File, excludeSet: Set? = null, dirFiles: Array } catch (e: Exception) { } if (!isSymbolicLink) { - val encodedHref = if (isLinkedDirectory) { "./${fileName.urlEncodePath()}/" } else { "./${fileName.urlEncodePath()}" } - val ariaLabel = "${fileName} ${if (isLinkedDirectory) { "디렉토리" } else { "파일" }}".escapeHtml() - val typeLabel = if (isLinkedDirectory) { "디렉토리" } else { "파일" } - val icon = if (isLinkedDirectory) { "📁" } else { "📄" } - l.append("""
  • ${fileName.escapeHtml()} ${typeLabel}
  • """) - l.append('\n') + val typeLabel = if (isLinkedDirectory) "디렉토리" else "파일" + val icon = if (isLinkedDirectory) "📁" else "📄" + val escapedName = fileName.escapeHtml() + + l.append("
  • ") + l.append(icon) + l.append(" ") + l.append(escapedName) + l.append(" ") + l.append(typeLabel) + l.append("
  • \n") } } } From 92244c75c97296f0e1f4e1aa2e06059043234ec8 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 25 Sep 2026 09:07:42 +0000 Subject: [PATCH 2/8] =?UTF-8?q?=E2=9A=A1=20Bolt:=20[=EB=A3=A8=ED=94=84=20?= =?UTF-8?q?=EB=82=B4=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=B5=9C=EC=A0=81=ED=99=94]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 복잡한 템플릿 문자열 보간을 `StringBuilder` 체이닝으로 교체 - 루프 핫 패스에서 중간 객체 할당 및 가비지 컬렉션 부하 감소 - 불필요한 중복 `escapeHtml()` 호출 제거 From 875daccb6f291941eae741d9dc5370a8dff69ec1 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 25 Sep 2026 16:50:23 +0000 Subject: [PATCH 3/8] =?UTF-8?q?=E2=9A=A1=20Bolt:=20[=EB=A3=A8=ED=94=84=20?= =?UTF-8?q?=EB=82=B4=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=B5=9C=EC=A0=81=ED=99=94]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 복잡한 템플릿 문자열 보간을 `StringBuilder` 체이닝으로 교체 - 루프 핫 패스에서 중간 객체 할당 및 가비지 컬렉션 부하 감소 - 불필요한 중복 `escapeHtml()` 호출 제거 From aed0431b287583e6de260f1d2a41fe5bce9381d7 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 25 Sep 2026 22:56:25 +0000 Subject: [PATCH 4/8] =?UTF-8?q?=E2=9A=A1=20Bolt:=20[=EB=A3=A8=ED=94=84=20?= =?UTF-8?q?=EB=82=B4=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=B5=9C=EC=A0=81=ED=99=94]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 복잡한 템플릿 문자열 보간을 `StringBuilder` 체이닝으로 교체 - 루프 핫 패스에서 중간 객체 할당 및 가비지 컬렉션 부하 감소 - 불필요한 중복 `escapeHtml()` 호출 제거 From ab17438d06aae14ad289acd6ab4fb5d1db097bfb Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 26 Sep 2026 04:39:52 +0000 Subject: [PATCH 5/8] =?UTF-8?q?=E2=9A=A1=20Bolt:=20[=EB=A3=A8=ED=94=84=20?= =?UTF-8?q?=EB=82=B4=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=B5=9C=EC=A0=81=ED=99=94]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 복잡한 템플릿 문자열 보간을 `StringBuilder` 체이닝으로 교체 - 루프 핫 패스에서 중간 객체 할당 및 가비지 컬렉션 부하 감소 - 불필요한 중복 `escapeHtml()` 호출 제거 From 11aadefab8e90c8c75d0ea1373f623b2c6643aa6 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 26 Sep 2026 09:56:16 +0000 Subject: [PATCH 6/8] =?UTF-8?q?=E2=9A=A1=20Bolt:=20[=EB=A3=A8=ED=94=84=20?= =?UTF-8?q?=EB=82=B4=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=B5=9C=EC=A0=81=ED=99=94]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 복잡한 템플릿 문자열 보간을 `StringBuilder` 체이닝으로 교체 - 루프 핫 패스에서 중간 객체 할당 및 가비지 컬렉션 부하 감소 - 불필요한 중복 `escapeHtml()` 호출 제거 From fb240c91d38e38359e73df07c1449a2e6d7f9e5b Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 26 Sep 2026 16:40:59 +0000 Subject: [PATCH 7/8] =?UTF-8?q?=E2=9A=A1=20Bolt:=20[=EB=A3=A8=ED=94=84=20?= =?UTF-8?q?=EB=82=B4=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=B5=9C=EC=A0=81=ED=99=94]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 복잡한 템플릿 문자열 보간을 `StringBuilder` 체이닝으로 교체 - 루프 핫 패스에서 중간 객체 할당 및 가비지 컬렉션 부하 감소 - 불필요한 중복 `escapeHtml()` 호출 제거 From 85c2691c9b9329d25cd2f4e1279a19bcbcb1253b Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 27 Sep 2026 09:44:27 +0000 Subject: [PATCH 8/8] =?UTF-8?q?=E2=9A=A1=20Bolt:=20[=EB=A3=A8=ED=94=84=20?= =?UTF-8?q?=EB=82=B4=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=B5=9C=EC=A0=81=ED=99=94]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 복잡한 템플릿 문자열 보간을 `StringBuilder` 체이닝으로 교체 - 루프 핫 패스에서 중간 객체 할당 및 가비지 컬렉션 부하 감소 - 불필요한 중복 `escapeHtml()` 호출 제거