Skip to content

Commit 443ef52

Browse files
committed
Add warm up example
1 parent 58f09b2 commit 443ef52

File tree

4 files changed

+164
-0
lines changed

4 files changed

+164
-0
lines changed

.run/check-jvm-warmup.run.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="Check JVM warmup" type="GradleRunConfiguration" factoryName="Gradle">
3+
<ExternalSystemSettings>
4+
<option name="executionName" />
5+
<option name="externalProjectPath" value="$PROJECT_DIR$" />
6+
<option name="externalSystemIdString" value="GRADLE" />
7+
<option name="scriptParameters" value="" />
8+
<option name="taskDescriptions">
9+
<list />
10+
</option>
11+
<option name="taskNames">
12+
<list>
13+
<option value="jmh" />
14+
</list>
15+
</option>
16+
<option name="vmOptions" />
17+
</ExternalSystemSettings>
18+
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
19+
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
20+
<DebugAllEnabled>false</DebugAllEnabled>
21+
<ForceTestExec>false</ForceTestExec>
22+
<method v="2" />
23+
</configuration>
24+
</component>

build.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
plugins {
33
kotlin("jvm") version "1.8.21"
4+
id("me.champeau.jmh") version "0.7.1"
45
}
56

67
group = "org.example"
@@ -16,6 +17,11 @@ repositories {
1617

1718
dependencies {
1819
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2")
20+
21+
val jmhVersion = "1.36"
22+
implementation("org.openjdk.jmh:jmh-core:$jmhVersion")
23+
implementation("org.openjdk.jmh:jmh-generator-annprocess:$jmhVersion")
24+
1925
testImplementation(kotlin("test"))
2026
}
2127

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package cub
2+
3+
import cub.jvm.BacktrackingSudokuSolver
4+
import org.openjdk.jmh.annotations.*
5+
import java.util.concurrent.TimeUnit
6+
7+
/**
8+
* Runs Check JVM warmup task from idea configurations
9+
* to see the difference between first iterations and the next ones
10+
* To see the difference, just check Fork: N of 3 sections, e.g.
11+
*
12+
* # Fork: 1 of 3
13+
* Iteration 1: 27041458.000 ns/op
14+
* Iteration 2: 1750.000 ns/op
15+
* Iteration 3: 1750.000 ns/op
16+
* Iteration 4: 625.000 ns/op
17+
* Iteration 5: 1125.000 ns/op
18+
* Iteration 6: 791.000 ns/op
19+
* Iteration 7: 958.000 ns/op
20+
* Iteration 8: 792.000 ns/op
21+
* Iteration 9: 750.000 ns/op
22+
* Iteration 10: 1084.000 ns/op
23+
*
24+
* Here we can see that the first iteration takes more time than all others.
25+
* We see different time between attempts, it is ok since the processor spents time for time measurement operations,
26+
* it affects to the results, but the time here is in nano secs, the difference is not significant.
27+
**/
28+
open class BenchmarkRunner {
29+
companion object {
30+
private const val BENCHMARK_ITERATIONS = 10
31+
private const val BENCHMARK_FORKS = 3
32+
private const val BENCHMARK_WARMUPS = 0
33+
}
34+
@Benchmark
35+
@BenchmarkMode(Mode.SingleShotTime)
36+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
37+
@Measurement(iterations = BENCHMARK_ITERATIONS)
38+
@Fork(value = BENCHMARK_FORKS, warmups = BENCHMARK_WARMUPS)
39+
fun solveSudoku() {
40+
val solver = BacktrackingSudokuSolver()
41+
solver.solve()
42+
}
43+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package cub.jvm
2+
3+
// Just a simple class with some computations
4+
class BacktrackingSudokuSolver {
5+
6+
fun printBoard() {
7+
board.forEach { row ->
8+
row.forEach { print("$it ") }
9+
println()
10+
}
11+
}
12+
13+
fun solve(): Boolean {
14+
board.forEachIndexed { i, row ->
15+
row.forEachIndexed { j, column ->
16+
if (board[i][j] == NO_VALUE) {
17+
for (k in MIN_VALUE..MAX_VALUE) {
18+
board[i][j] = k
19+
if (isValid(i, j) && solve()) {
20+
return true
21+
}
22+
board[i][j] = NO_VALUE
23+
}
24+
return false
25+
}
26+
}
27+
}
28+
return true
29+
}
30+
31+
private fun isValid(row: Int, column: Int): Boolean {
32+
return rowConstraint(row) &&
33+
columnConstraint(column) &&
34+
subsectionConstraint(row, column)
35+
}
36+
37+
private fun subsectionConstraint(row: Int, column: Int): Boolean {
38+
val constraint = BooleanArray(BOARD_SIZE)
39+
val subsectionRowStart = row / SUBSECTION_SIZE * SUBSECTION_SIZE
40+
val subsectionRowEnd = subsectionRowStart + SUBSECTION_SIZE
41+
val subsectionColumnStart = column / SUBSECTION_SIZE * SUBSECTION_SIZE
42+
val subsectionColumnEnd = subsectionColumnStart + SUBSECTION_SIZE
43+
for (r in subsectionRowStart until subsectionRowEnd) {
44+
for (c in subsectionColumnStart until subsectionColumnEnd) {
45+
if (!checkConstraint(r, constraint, c)) return false
46+
}
47+
}
48+
return true
49+
}
50+
51+
private fun columnConstraint(column: Int): Boolean {
52+
val constraint = BooleanArray(BOARD_SIZE)
53+
return (BOARD_START_INDEX until BOARD_SIZE).all { checkConstraint(it, constraint, column) }
54+
}
55+
56+
private fun rowConstraint(row: Int): Boolean {
57+
val constraint = BooleanArray(BOARD_SIZE)
58+
return (BOARD_START_INDEX until BOARD_SIZE).all { checkConstraint(row, constraint, it) }
59+
}
60+
61+
private fun checkConstraint(row: Int, constraint: BooleanArray, column: Int): Boolean {
62+
if (board[row][column] != NO_VALUE) {
63+
if (!constraint[board[row][column] - 1]) {
64+
constraint[board[row][column] - 1] = true
65+
} else {
66+
return false
67+
}
68+
}
69+
return true
70+
}
71+
72+
companion object {
73+
private const val BOARD_SIZE = 9
74+
private const val SUBSECTION_SIZE = 3
75+
private const val BOARD_START_INDEX = 0
76+
private const val NO_VALUE = 0
77+
private const val MIN_VALUE = 1
78+
private const val MAX_VALUE = 9
79+
private val board = arrayOf(
80+
intArrayOf(8, 0, 0, 0, 0, 0, 0, 0, 0),
81+
intArrayOf(0, 0, 3, 6, 0, 0, 0, 0, 0),
82+
intArrayOf(0, 7, 0, 0, 9, 0, 2, 0, 0),
83+
intArrayOf(0, 5, 0, 0, 0, 7, 0, 0, 0),
84+
intArrayOf(0, 0, 0, 0, 4, 5, 7, 0, 0),
85+
intArrayOf(0, 0, 0, 1, 0, 0, 0, 3, 0),
86+
intArrayOf(0, 0, 1, 0, 0, 0, 0, 6, 8),
87+
intArrayOf(0, 0, 8, 5, 0, 0, 0, 1, 0),
88+
intArrayOf(0, 9, 0, 0, 0, 0, 4, 0, 0)
89+
)
90+
}
91+
}

0 commit comments

Comments
 (0)