Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
# Ignore Gradle build output directory
build

.idea
.ideatest_dir/
6 changes: 3 additions & 3 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
## 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-05-24 - Optimize string concatenation in `process_dir` loop
**Learning:** String concatenation using `+=` inside loops where potentially thousands of string appending occurs causes performance issues due to excessive memory reallocation and copying. Kotlin's `StringBuilder` drastically improves performance.
**Action:** Replace string accumulation with `+=` inside loops with `StringBuilder.append()` when generating large dynamic strings like HTML.
6 changes: 6 additions & 0 deletions benchmark.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash
mkdir -p test_dir
for i in {1..5000}; do
touch test_dir/file_$i.txt
done
time export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 && ./gradlew run --args="test_dir" > /dev/null
18 changes: 18 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ buildscript {

apply plugin: 'kotlin'
apply plugin: 'application'
apply plugin: 'jacoco'

mainClassName = 'html4tree.MainKt'

Expand All @@ -33,4 +34,21 @@ jar {
}

from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}

jacocoTestReport {
reports {
xml.enabled true
html.enabled true
}
}

jacocoTestCoverageVerification {
violationRules {
rule {
limit {
minimum = 1.0
}
}
}
}
6 changes: 3 additions & 3 deletions src/main/kotlin/html4tree/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,17 @@ fun process_dir(curr_dir: File){
"""

val index_middle = fun():String{
var l=""
val l = StringBuilder()

val dir_files: MutableList<File> = curr_dir.listFiles().toMutableList()
dir_files.sortWith(compareBy ({it.name}) )
dir_files.forEach {
if((it.getName() !in exclude) && (it != curr_dir)) {
l += """ <li><a style="display:block; width:100%" href="${if (it.isDirectory()) { "./${it.getName().urlEncodePath()}/" } else { "./${it.getName().urlEncodePath()}" }}">${if (it.isDirectory()) { "&#128193;" } else { "&rtrif;" }} ${it.getName().escapeHtml()}</a></li>"""+"\n"
l.append(""" <li><a style="display:block; width:100%" href="${if (it.isDirectory()) { "./${it.getName().urlEncodePath()}/" } else { "./${it.getName().urlEncodePath()}" }}">${if (it.isDirectory()) { "&#128193;" } else { "&rtrif;" }} ${it.getName().escapeHtml()}</a></li>"""+"\n")
}
}

return l;
return l.toString();
}

val index_bottom="""
Expand Down
1 change: 1 addition & 0 deletions time.log
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
./time_test.sh: line 5: /usr/bin/time: No such file or directory
7 changes: 7 additions & 0 deletions time_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash
mkdir -p test_dir
for i in {1..5000}; do touch test_dir/file_$i.txt; done
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
./gradlew build
time java -jar build/libs/app.jar test_dir
rm -rf test_dir