0306 ~ 0319
# 0306 ~ 0319
# 0309 - JIT(Just-In Time compiler) ์ปดํ์ผ๋ฌ๋?
์๋ฐ๋ ์ฝ๋๋ฅผ ์คํํ๊ธฐ ์ํด์ ๋ฐ์ดํธ์ฝ๋๋ก ์ปดํ์ผํ๋ ๊ณผ์ ๊ณผ ๋ฐ์ดํธ์ฝ๋๋ฅผ ์ธํฐํ๋ฆฌํธํ๋ ๊ณผ์ ์ ๊ฑฐ์ณ์ผํ๊ธฐ ๋๋ฌธ์ ์ปดํ์ผ ๊ณผ์ ๋ง ํ์ํ ๋ค๋ฅธ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ณด๋ค ๋๋ฆฌ๋ค. ๊ฑฐ๊ธฐ์ ๋ํ์ฌ ์ธํฐํ๋ฆฌํฐ๋ ์ปดํ์ผ๋ฌ๋ณด๋ค ๋๋ฆฌ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ๋ฐ์ ์๋ค.
์ธํฐํ๋ฆฌํฐ ๋ฐฉ์์ ๋จ์ ์ ๋ณด์ํ๊ธฐ ์ํด ๋์ ๋๋ค. JIT ์ปดํ์ผ๋ฌ๋ ์คํ ์์ ์ ์ธํฐํ๋ฆฌํฐ ๋ฐฉ์์ผ๋ก ๊ธฐ๊ณ์ด ์ฝ๋๋ฅผ ์์ฑํ ๋ ์์ฃผ ์ฌ์ฉ๋๋ ๋ฉ์๋์ ๊ฒฝ์ฐ ์ปดํ์ผํ๊ณ ๊ธฐ๊ณ์ด๋ฅผ ์บ์ฑํ๋ค. ๊ทธ๋ฆฌ๊ณ ํด๋น ๋ฉ์๋๊ฐ ์ฌ๋ฌ ๋ฒ ํธ์ถํ ๋ ๋งค๋ฒ ํด์ํ๋ ๊ฒ์ ๋ฐฉ์งํ๋ค.
# [ JIT ์ปดํ์ผ๋ฌ ๋์ ๋ฐฉ์ ]
JIT ์ปดํ์ผ๋ฌ๋ ์คํ ์์ ์์๋ ์ธํฐํ๋ฆฌํฐ์ ๊ฐ์ด ๊ธฐ๊ณ์ด ์ฝ๋๋ฅผ ์์ฑํ๋ฉด์ ํด๋น ์ฝ๋๊ฐ ์ปดํ์ผ ๋์์ด ๋๋ฉด ์ปดํ์ผํ๊ณ ๊ทธ ์ฝ๋๋ฅผ ์บ์ฑํ๋ค. JIT ์ปดํ์ผ์ ์ฝ๋๊ฐ ์คํ๋๋ ๊ณผ์ ์ ์ค์๊ฐ์ผ๋ก ์ผ์ด๋๋ฉฐ, ์ ์ฒด ์ฝ๋์ ํ์ํ ๋ถ๋ถ๋ง ๋ณํํ๋ค. ๊ธฐ๊ณ์ด๋ก ๋ณํ๋ ์ฝ๋๋ ์บ์์ ์ ์ฅ๋๊ธฐ ๋๋ฌธ์ ์ฌ์ฌ์ฉ ์ ์ปดํ์ผ์ ๋ค์ ํ ํ์๊ฐ ์๋ค.
- JIT ์ปดํ์ผ๋ฌ๊ฐ ์ปดํ์ผํ๋ ์กฐ๊ฑด์ ์ผ๋ง๋ ์์ฃผ ์ฝ๋๊ฐ ์คํ๋๋๊ฐ ์ด๋ค. ์ผ์ ํ ํ์๋งํผ ์คํ๋๊ณ ๋๋ฉด ์ปดํ์ผ ์๊ณ์น์ ๋๋ฌํ๊ณ ์ปดํ์ผ๋ฌ๋ ์ปดํ์ผํ๊ธฐ์ ์ถฉ๋ถํ ์ ๋ณด๊ฐ ์์๋ค๊ณ ์๊ฐํ๋ค.
- ์๊ณ์น๋ ๋ฉ์๋๊ฐ ํธ์ถ๋ ํ์, ๋ฉ์๋์ ๋ฃจํ๋ฅผ ๋น ์ ธ๋์ค๊ธฐ๊น์ง ๋ ํ์ ๋ ๊ฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ค. ์ด ๋ ์์ ํฉ๊ณ๋ฅผ ํ์ธํ๊ณ ๋ฉ์๋๊ฐ ์ปดํ์ผ๋ ์๊ฒฉ์ด ์๋์ง ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ค. ์๊ฒฉ์ด ์๋ค๋ฉด ๋ฉ์๋๋ ์ปดํ์ผ๋๊ธฐ ์ํด ํ์์ ๋๊ธฐํ๋ค. ์ดํ ๋ฉ์๋๋ค์ ์ปดํ์ผ ์ค๋ ๋์ ์ํด ์ปดํ์ผ๋๋ค.
- ์์ฃผ ์ค๋ซ๋์ ๋์๊ฐ๋ ๋ฃจํ ๋ฌธ์ ์นด์ดํฐ๊ฐ ์๊ณ์น๋ฅผ ๋์ด๊ฐ๋ฉด ํด๋น ๋ฃจํ๋ ์ปดํ์ผ ๋์์ด ๋๋ค. JVM์ ๋ฃจํ๋ฅผ ์ํ ์ฝ๋์ ์ปดํ์ผ์ด ๋๋๋ฉด ๋ฃจํ๊ฐ ๋ค์ ๋ฐ๋ณต๋ ๋๋ ์ฝ๋๋ฅผ ์ปดํ์ผ๋ ์ฝ๋๋ก ๊ต์ฒดํ๊ณ ๋ ๋น ๋ฅด๊ฒ ์คํ๋๋ค. ์ด ๊ต์ฒด ๊ณผ์ ์ "์คํ ์์ ๊ต์ฒด(on-stack replacement, ORS)"๋ผ๊ณ ๋ถ๋ฅธ๋ค.
์ปดํ์ผ ์๊ณ์น(Compile Threshold) : JIT ์ปดํ์ผ๋ฌ๊ฐ ๋ฉ์๋๊ฐ ์์ฃผ ์ฌ์ฉ๋๋์ง ์ฒดํฌํ๋ ๋ฐฉ์์ผ๋ก ์ปดํ์ผ ์๊ณ์น๋ฅผ ์ฌ์ฉํ๋ค. JIT ์ปดํ์ผ๋ฌ๊ฐ ๋ด๋ถ์ ์ผ๋ก ๋ฉ์๋๊ฐ ํธ์ถ๋ ๋๋ง๋ค ํธ์ถ ํ์๋ฅผ ์นด์ดํ ํ๊ณ ๊ทธ ํ์๊ฐ ํน์ ์์น๋ฅผ ์ด๊ณผํ ๋ ์บ์ฑํค์ ์ดํ์๋ JIT ์ปดํ์ผ์ด ํธ๊ธฐ๋ฌ๋๋ค.
# [ ์ด์ ]
์ผ๋ฐ์ ์ธ ์ธํฐํ๋ฆฌํฐ ์ธ์ด๋ ๋ฐ์ดํธ์ฝ๋๋ ์์ค์ฝ๋๋ฅผ ์ต์ ํ ๊ณผ์ ์ด ์์ด ๋ฒ์ญํ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ด ๋ฎ๋ค. ๋ฐ๋ฉด ์ ์ ์ผ๋ก ์ปดํ์ผํ๋ ์ธ์ด๋ ์คํ ์ ์ ๋ฌด์กฐ๊ฑด ์ปดํ์ผ์ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ค์ํ ํ๋ซํผ์ ๋ง๊ฒ ์ปดํ์ผ์ ํ๋ ค๋ฉด ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฐ๋ค. JIT ์ปดํ์ผ๋ฌ๋ ์คํ ๊ณผ์ ์์ ์ปดํ์ผ์ ํ ์ ์๊ธฐ ์ํด ๋ง๋ค์ด์ก๋ค. JIT ์ปดํ์ผ๋ฌ๋ ์ ์ ์ปดํ์ผ๋ฌ๋งํผ ๋น ๋ฅด๋ฉด์ ์ธํฐํ๋ฆฌํฐ ์ธ์ด์ ๋น ๋ฅธ ์๋ต์๋๋ฅผ ์ถ๊ตฌํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค. ๋ํ ๋ฐ์ดํธ์ฝ๋ ์ปดํ์ผ๋ฌ๊ฐ ์๊ฐ์ด ๋ง์ด ์์๋๋ ์ต์ ํ๋ฅผ ๋ฏธ๋ฆฌ ํด์ฃผ๊ธฐ ๋๋ฌธ์ ๋ฐ์ดํธ ์ฝ๋์์ ๊ธฐ๊ณ์ด ๋ฒ์ญ์ ํจ์ฌ ๋น ๋ฅด๊ฒ ์งํ๋ ์ ์์ด ์ฑ๋ฅ์์ ์ด์ ์ด ์๋ค.
# 0310 - ์๋ฐ์์ ๋ณ๋ ฌ ์คํธ๋ฆผ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ
Java 8์์๋ ์ปฌ๋ ์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ผ๋ก ์ฝ๊ฒ ๋ฐ๋ณตํ ์ ์๋ Stream API๋ฅผ ๋์ ํ๋ค.
# ์์ฐจ ์คํธ๋ฆผ
- ๋จ์ผ ์ค๋ ๋ ์ฒ๋ฆฌ
List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
listOfNumbers.stream().forEach(number ->
System.out.println(number + " " + Thread.currentThread().getName())
);
2
3
4
์คํ๊ฒฐ๊ณผ :
1 main
2 main
3 main
4 main
2
3
4
5
# ๋ณ๋ ฌ ์คํธ๋ฆผ
List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
listOfNumbers.parallelStream().forEach(number ->
System.out.println(number + " " + Thread.currentThread().getName())
);
2
3
4
4 ForkJoinPool.commonPool-worker-3
2 ForkJoinPool.commonPool-worker-5
1 ForkJoinPool.commonPool-worker-7
3 main
2
3
4
# [ Fork-Join Framework ]
๋ณ๋ ฌ ์คํธ๋ฆผ์ Fork-Join ํ๋ ์์ํฌ์ common pool of worker ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ค. fork-join ํ๋ ์์ํฌ๋ ์ฌ๋ฌ ์ค๋ ๋๊ฐ์ ์์ ๊ด๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด Java7์ java.util.concurrent์ ์ถ๊ฐ๋์๋ค.
# [ ์์ค ๋ถํ ]
fork-join ํ๋ ์์ํฌ๋ worker ์ค๋ ๋๊ฐ์ ์์ค ๋ฐ์ดํฐ๋ฅผ ๋ถํ ํ๊ณ ์์ ์๋ฃ์ ์ฝ๋ฐฑ์ ์ฒ๋ฆฌํ๋ ์ญํ ์ ํ๋ค.
List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
int sum = listOfNumbers.parallelStream().reduce(5, Integer::sum);
assertThat(sum).isNotEqualTo(15);
2
3
์์ฐจ์คํธ๋ฆผ์์์ ์์ ๊ฒฐ๊ณผ๋ 15์ด๋, ๋ณ๋ ฌ ์ฒ๋ฆฌ์ ์ค์ ๋ชจ๋ ์์ปค ์ค๋ ๋์์ ์ซ์ 5๊ฐ ํฉ์ฐ๋๋ค.
List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
int sum = listOfNumbers.parallelStream().reduce(0, Integer::sum) + 5;
assertThat(sum).isEqualTo(15);
2
3
๋ณ๋ ฌ ์คํธ๋ฆผ ์ธ๋ถ์ ์ซ์ 5๋ฅผ ๋ํ๋ ์์ ์ ํตํด ๋ฌธ์ ํด๊ฒฐ
# [ common thread pool ]
common ์ค๋ ๋ํ์ ์ค๋ ๋ ์๋ ํ๋ก์ธ์ ์ฝ์ด ์์ ๊ฐ๋ค. ๊ทธ๋ฌ๋ API๋ฅผ ์ฌ์ฉํ๋ฉด JVM ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฌํ์ฌ ์ฌ์ฉํ ์ค๋ ๋์๋ฅผ ์ง์ ํ ์ ์๋ค.
-D java.util.concurrent.ForkJoinPool.common.parallelism=4
์ด๊ฒ์ ์ ์ญ์ผ๋ก ์ค์ ํ๋ ๊ฒ์ด๋ฉฐ, common thread pool์ ์ฌ์ฉํ๋ ๋ชจ๋ ๋ณ๋ ฌ ์คํธ๋ฆผ ๋ฐ ๊ธฐํ ๋ชจ๋ fork-join ์์ ์ ์ํฅ์ ๋ฏธ์น๋ค. ์ฌ์ฉ์ ์ฃผ์
# [ custom thread pool ]
List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
ForkJoinPool customThreadPool = new ForkJoinPool(4);
int sum = customThreadPool.submit(
() -> listOfNumbers.parallelStream().reduce(0, Integer::sum)).get();
customThreadPool.shutdown();
assertThat(sum).isEqualTo(10);
2
3
4
5
6
# [ ์ฑ๋ฅ์์ ์ํฅ ]
๋ณ๋ ฌ ์ฒ๋ฆฌ๋ ๋ค์ค ์ฝ์ด๋ฅผ ์จ์ ํ ํ์ฉํ ์ ์๋ค. ๊ทธ๋ฌ๋ ๋ค์ค ์ค๋ ๋ ๊ด๋ฆฌ, ๋ฉ๋ชจ๋ฆฌ ์ง์ญ์ฑ, ์์ค ๋ถํ ๋ฐ ๊ฒฐ๊ณผ ๋ณํฉ์ ๋ํ ์ค๋ฒํค๋๋ ๊ณ ๋ คํด์ผ ํ๋ค.
# [ ์ค๋ฒํค๋(Overhead) ]
IntStream.rangeClosed(1, 100).reduce(0, Integer::sum);
IntStream.rangeClosed(1, 100).parallel().reduce(0, Integer::sum);
2
์ด๋ฐ ๊ฐ๋จํ ํฉ๊ณ์์ ์์ฐจ ์คํธ๋ฆผ์ ๋ณ๋ ฌ ์คํธ๋ฆผ์ผ๋ก ๋ณํํ๋ฉด ์ฑ๋ฅ์ด ์ ํ๋๋ค.
๊ทธ ์ด์ ๋ ๋๋๋ก ์ค๋ ๋, ์์ค ๋ฐ ๊ฒฐ๊ณผ๋ฅผ ๊ด๋ฆฌํ๋ ์ค๋ฒํค๋๊ฐ ์ค์ ์์ ์ ์ํํ๋ ๊ฒ๋ณด๋ค cost๊ฐ ๋ง์ด ๋๋ ์์ ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
# [ ๋ถํ ๋น์ฉ(Splitting Costs) ]
๋ฐ์ดํฐ ์์ค(๊ฐ๊ฐ์ ์คํธ๋ฆผ ๋จ์)๋ฅผ ๊ท ๋ฑํ๊ฒ ๋ถํ ํ๋ ๊ฒ์ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ํ๋๋ฐ ํ์ํ cost์ด์ง๋ง ์ผ๋ถ ๋ฐ์ดํฐ ์์ค๋ ๋ค๋ฅธ ๋ฐ์ดํฐ ์์ค๋ณด๋ค ๋ ์๋ถํ ๋๋ค.
private static final List<Integer> arrayListOfNumbers = new ArrayList<>();
private static final List<Integer> linkedListOfNumbers = new LinkedList<>();
// ํด๋น ์ฝ๋๋ก 100๋ง์ ์ ์ ๋ชฉ๋ก์ ์ด๊ธฐํํฉ๋๋ค.
static {
IntStream.rangeClosed(1, 1_000_000).forEach(i -> {
arrayListOfNumbers.add(i);
linkedListOfNumbers.add(i);
});
}
2
3
4
5
6
7
8
9
10
arrayListOfNumbers.stream().reduce(0, Integer::sum)
arrayListOfNumbers.parallelStream().reduce(0, Integer::sum);
linkedListOfNumbers.stream().reduce(0, Integer::sum);
linkedListOfNumbers.parallelStream().reduce(0, Integer::sum);
2
3
4
์๋์ ๊ฒฐ๊ณผ๋ ์์ฐจ ์คํธ๋ฆผ์ ๋ณ๋ ฌ ์คํธ๋ฆผ์ผ๋ก ๋ณํํ๋ ๊ฒ์ด ArrayList์ ๋ํด์๋ง ์ฑ๋ฅ ์ด์ ์ ๊ฐ์ ธ์จ๋ค๋ ๊ฒ์ ๋ณด์ฌ์ค๋ค.
LinkedList๋ ๋ณ๋ ฌ์ฒ๋ฆฌ๋ฅผ ํ์ง๋ง Scoredhk Error ๊ฐ์ด ์ฆ๊ฐ, ๋ฐ๋ฉด ArrayList๋ Score์ Error ๊ฐ์ด ๊ฐ์
๊ทธ ์ด์ ๋ Array๋ผ๋ ํน์ง์ด ์ ๋ ดํ๊ฒ ์์ค๋ฅผ ๋ถํ ํ ์ ์์ง๋ง LinkedList์๋ ์ด๋ฌํ ์์ฑ์ด ์๊ธฐ ๋๋ฌธ์ด๋ค. TreeMap๊ณผ HashSet์ LinkedList๋ณด๋ค ์ ๋ถํ ๋์ง๋ง Array๋งํผ์ ๋ถํ ๋์ง ์ํ๋ค.
# [ ๋ณํฉ ๋น์ฉ(Merging Costs) ]
๋ณ๋ ฌ ๊ณ์ฐ์ ํ๊ธฐ ์ํด ์์ค๋ฅผ ๋ถํ ํ ๋๋ง๋ค ๊ฒฐ๊ตญ ๊ฒฐ๊ณผ๋ฅผ ๋ณํฉํด์ผ ํ๋ค. ์๋ก ๋ค๋ฅธ ๋ณํฉ ์์ ์ผ๋ก sum ๋ฐ grouping์ ์ฌ์ฉํ์ฌ ์์ฐจ ๋ฐ ๋ณ๋ ฌ ์คํธ๋ฆผ์์์ ์ฑ๋ฅ ํ ์คํธ๋ฅผ ์คํ
arrayListOfNumbers.stream().reduce(0, Integer::sum);
arrayListOfNumbers.stream().parallel().reduce(0, Integer::sum);
arrayListOfNumbers.stream().collect(Collectors.toSet());
arrayListOfNumbers.stream().parallel().collect(Collectors.toSet());
2
3
4
์๋์ ๊ฒฐ๊ณผ๋ ์์ฐจ ์คํธ๋ฆผ์ ๋ณ๋ ฌ ์คํธ๋ฆผ์ผ๋ก ๋ณํํ๋ ๊ฒ์ด sum ์ฐ์ฐ์ ๋ํด์๋ง ์ฑ๋ฅ์์ ์ด์ ์ ๊ฐ์ ธ์จ๋ค๋ ๊ฒ์ ๋ณด์ฌ์ค๋ค.
๋ณํฉ ์์ ์ reduce์ sum๊ณผ ๊ฐ์ ์ผ๋ถ ์์ ์ ๊ฒฝ์ฐ ์ ๋ง ๊ฐ๋ณ๊ฒ ๋์ํ์ง๋ง set๊ณผ map๊ณผ ๊ฐ์ ํํ๋ก ๊ทธ๋ฃนํํ๋ ๊ฒ์ ๋ณํฉ ์์ ์ด ์๋นํ ๋ฌด๊ฒ๊ฒ ๋์ํ ์ ์๋ค.
# [ Memory Locality ]
์ต์ ์ปดํจํฐ๋ ์ ๊ตํ ๋ฉํฐ ๋ ๋ฒจ ์บ์๋ฅผ ํ์ฉํ์ฌ ์์ฃผ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ๋ฅผ ํ๋ก์ธ์ ๊ฐ๊น์ด์ ์ ์ฅํ๋ค. ์ ํ ๋ฉ๋ชจ๋ฆฌ ์์ธ์ค ํจํด์ด ๊ฐ์ง๋๋ฉด ํ๋์จ์ด๋ ๊ณง ํ์ํ ๊ฒ์ด๋ผ๋ ๊ฐ์ ํ์ ๋ค์ ๋ฐ์ดํฐ ๋ผ์ธ์ ๋ฏธ๋ฆฌ ๊ฐ์ ธ์จ๋ค.(prefetch)
๋ณ๋ ฌ ์ฒ๋ฆฌ๋ ํ๋ก์ธ์ ์ฝ์ด๊ฐ ์ ์ฉํ ์์
์ ์ง์์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ ๋ ์ฑ๋ฅ ์ด์ ์ ๊ฐ์ ธ์จ๋ค. cache miss๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ ์ ์ฉํ ์์
์ด ์๋๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ๋์ญํญ์ ์ ํ ์์๋ก ๊ณ ๋ คํด์ผ ํ๋ค.
ํ๋๋ primitive ํ์
์ ์ฌ์ฉํ๊ณ ๋ค๋ฅธ ํ๋๋ wrapper ํ์
์ ์ฌ์ฉํ๋ ๋๊ฐ์ ๋ฐฐ์ด์ ์ฌ์ฉํ์ฌ ์ด๋ฅผ ์ฆ๋ช
ํ๋ ์์ด๋ค.
private static final int[] intArray = new int[1_000_000];
private static final Integer[] integerArray = new Integer[1_000_000];
static {
IntStream.rangeClosed(1, 1_000_000).forEach(i -> {
intArray[i-1] = i;
integerArray[i-1] = i;
});
}
2
3
4
5
6
7
8
9
๋ ๋ฐฐ์ด์์ ์์ฐจ ๋ฐ ๋ณ๋ ฌ reduce ์์ ์ ๋ํ ์ฑ๋ฅ ํ ์คํธ๋ฅผ ์คํํด๋ณด์
Arrays.stream(intArray).reduce(0, Integer::sum);
Arrays.stream(intArray).parallel().reduce(0, Integer::sum);
Arrays.stream(integerArray).reduce(0, Integer::sum);
Arrays.stream(integerArray).parallel().reduce(0, Integer::sum);
2
3
4
์๋์ ๊ฒฐ๊ณผ ์์ฐจ ์คํธ๋ฆผ์ ๋ณ๋ ฌ ์คํธ๋ฆผ์ผ๋ก ๋ณํํ๋ ๊ฒ์ด primitive ๋ฐฐ์ด์ ์ฌ์ฉํ ๋ ์ฝ๊ฐ ๋ ๋ง์ ์ฑ๋ฅ ์ด์ ์ ๊ฐ์ ธ์จ๋ค.
# [ NQ๋ชจ๋ธ ]
NQ๋ชจ๋ธ์์๋ N์ ์์ค ๋ฐ์ดํฐ์ ์์ ์๋ฅผ ๋ํ๋ด๊ณ Qs๋ ๋ฐ์ดํฐ ์์๋น ์ํ๋ ๊ณ์ฐ์ ์์ ๋ํ๋ธ๋ค.
N * Q์ ๊ณฑ์ด ํด์๋ก ๋ณ๋ ฌํ๋ก ์ธํด ์ฑ๋ฅ ํฅ์์ ๊ฐ๋ฅ์ฑ์ด ๋์์ง๋ค. ์ซ์ ํฉ์ฐ๊ณผ ๊ฐ์ด ์ฌ์ํ Q๊ฐ ์๋ ๋ฌธ์ ์ ๊ฒฝ์ฐ ๊ฒฝํ์ N์ 10,000 ๋ณด๋ค ์ปค์ผ ํ๋ค.
# 0317 - JMH(Java Microbenchmark Harness)
JMH๋ JVM ์์์ ๋์ํ๋ ์ฝ๋์ ์ฑ๋ฅ์ ์ธก์ ํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค. ์ฌ์ค ์ ํํ ์ฑ๋ฅ์ ์ธก์ ํ๊ธฐ ์ํด์ ์ฌ์ฉํ๋ ๊ฐ์๋จธ์ ์ ์ ํ์ ๋ฐ๋ผ Hot-Spot VM ์ค๋ฒํค๋๋ GC ์ค๋ฒํค๋์ ๊ฐ์ ์ฝ๋๊ฐ ๋์ํจ์ ์์ด์ ์์คํ ์ ์ค๋ฒํค๋๊น์ง ๊ณ ๋ คํด์ ์ธก์ ํด์ผ ํ์ง๋ง ๊ฐ๋จํ ์ฝ๋์ด๊ฑฐ๋ ์ฌ๋ฌ ์ฝ๋์ ์๋์ ์ฑ๋ฅ์ ์ธก์ ํ ๋์๋ ๊ฐ๋จํ ์ฌ์ฉํ ์ ์๋ JMH๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
์ฐธ๊ณ ๋ก, JMH๋ Oracle์ JIT Compiler ๊ฐ๋ฐ์๊ฐ ๋ง๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ํ ๋ฒค์น๋งํฌ ํ๋ ์์ํฌ๋ณด๋ค ์ ๋ขฐํ ์ ์๋ค.
# [ ์ฌ์ฉ๋ฐฉ๋ฒ ]
plugins {
id "me.champeau.jmh" version "0.7.0"
}
dependencies {
jmh 'org.openjdk.jmh:jmh-core:0.9'
jmh 'org.openjdk.jmh:jmh-generator-annprocess:0.9'
}
2
3
4
5
6
7
8
@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class LoopTest {
final LIMIT_COUNT = 10000;
final List<Integer> array = new ArrayList<>();
@Setup
public void init() {
// ์ฑ๋ฅ ์ธก์ ์ ์ฌ์ ์ ํ์ํ ์์
for(int i = 0; i < LIMIT_COUNT; i++) {
array.add(i);
}
}
@Benchmark
public void originLoopWithGetSize() {
// ์ฑ๋ฅ์ ์ธก์ ํ ์ฝ๋ ์์ฑ
int size = array.size();
for(int i = 0; i < size; i++) {
processor(i);
}
}
Integer temp = 0;
public void processor(Integer i) {
temp = i;
}
public static void main(String[] args) throws IOException, RunnerException {
Options opt = new OptionsBuilder()
.include(LoopTest.class.getSimpleName())
.warmupIterations(10) // ์ฌ์ ํ
์คํธ ํ์
.measurementIterations(10) // ์ค์ ์ธก์ ํ์
.forks(1) //
.build();
new Runner(opt).run(); // ๋ฒค์น๋งํน ์์
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Run complete. Total time: 00:01:43
Benchmark Mode Cnt Score Error Units
LoopTest.forEach avgt 10 0.990 ยฑ 0.096 ms/op
LoopTest.forEachByJdk8 avgt 10 0.703 ยฑ 0.160 ms/op
LoopTest.forEachByStream avgt 10 0.561 ยฑ 0.057 ms/op
LoopTest.originLoop avgt 10 0.634 ยฑ 0.117 ms/op
LoopTest.originLoopWithGetSize avgt 10 0.876 ยฑ 0.093 ms/op
2
3
4
5
6
7
8
# 0319 - KPI/SLI/SLO/SLA
# 1. KPI(Key Performance Indicator)
KPI(Key Performance Indicator)๋ ์ฑ๊ณต์ ์ธก์ ํ๋๋ฐ ์ฌ์ฉ๋ ์ ์๋ ๋ฉํธ๋ฆญ์ด๋ค.
- KPI๋ ๋ชฉํ๋ ๋ชฉ์ ๊ณผ๋ ๋ค๋ฅธ, ๋ชฉํ๋ฅด๋ฅด ๋ฌ์ฑํ๋ ๊ณผ์ ์ค์ ์๋์ง ์ธก์ ํ๋ ๋ฉํธ๋ฆญ์ด๋ค. ๋ฐ๋ผ์ ์๋ฐํ๋ ๋ชฉํ๊ฐ ํ์ํ๋ค. ๋ํ, KPI๋ฅผ ๋ชจ๋ํฐ๋งํ๋ ๊ฒ์ ๋ชฉํ๋ฅผ ๋ฌ์ฑํ๊ธฐ ์ํด ํ์์ ์ด๋ค.
- SMART ๋ฒ์น
- Specific : KPI๋ ๊ตฌ์ฒด์ ์ด์ด์ผ ํ๋ค.
- Measurable : ๋ชจ๋ํฐ๋งํ๊ธฐ ์ํด์ KPI๋ ์ธก์ ๊ฐ๋ฅํด์ผ ํ๋ค.
- Acheivable : 100%๋ ์ฑ์ทจํ๊ธฐ ์ด๋ ต๋ค.
- Relevant : ๊ด๋ จ์์ง ์์ KPI๋ ๋ชฉํ ๋ฌ์ฑ์ ์ด๋์ด ๋ผ ์ ์๋ค.
- Time-bound : 99% availble- Per year? Per month? Per day?
# 2. Service Level
Indicators -> Objectives -> Agreement
# [ SLI(Service Level Indicators) ]
: ์๋น์ค์ ์ธก์ ๊ฐ๋ฅํ ํน์ฑ, A KPI
ex. Availability
SLI๋ ์๊ฐ์ด ์ ํด์ง๊ณ ์ธก์ ๊ฐ๋ฅํด์ผ ํ๋ค.
# [ SLO(Service Level Objectives) ]
: ์ฃผ์ด์ง SLI๋ก ์ฑ์ทจํ๊ณ ์ถ์ ๋ชฉํ๋ ์ซ์ ์งํ
ex. 95%, 99% or 99.99% availability
SLO๋ ์ฑ์ทจ ๊ฐ๋ฅํ๊ณ ๊ด๋ จ ์์ด์ผ ํ๋ค.
๊ฐ๋ฅํ ๋์ ๋ชฉํ๋ฅผ ์ธ์ฐ๋ ๊ฒ์ด ์๋๋ผ, ์ฌ์ฉ์๋ฅผ ๋ง์กฑ์ํฌ ๋งํผ์์ ๊ฐ๊ฒฉ ํจ์จ์ ์ธ SLO๋ฅผ ์ ํํด์ผํ๋ค. SLO๊ฐ ๋์์๋ก ๋์ ๋น์ฉ๊ณผ ๋ ธ๋ ฅ์ ์ด๋ํ๊ธฐ ๋๋ฌธ์ด๋ค.
SLO๋ฅผ ์ต์ํ ํด์ผํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ดํ๋ฆฌ์ผ์ด์ ์ด SLO๋ฅผ ํฌ๊ฒ ๋ฅ๊ฐํด์๋ ์๋๋ค.
# [ SLA(Service Level Agreements) ]
: ๋ง์ฝ ์๋น์ค๊ฐ ํน์ ๊ธฐ๋๋ฅผ ๋ชป ๋ฏธ์ณค์ ๋, ๊ณ ๊ฐ ๋ณด์์ ์ ๊ณตํด์ฃผ๋ ๊ตฌ์๋ ฅ์๋ ๊ณ์ฝ
= more restrictive version of SLO
SLA์๋ ๋ง์ฝ ์๋น์ค๊ฐ ํน์ ๊ฐ์ฉ์ฑ์ ๋๋ ํผํฌ๋จผ์ค ๊ธฐ์ค์ ์ ์งํ์ง ๋ชปํ์๋ ์ ๊ณต์์ ๊ฐํด์ง๋ penalty์ ๋ํ์ฌ ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ SLA๊ฐ ๊นจ์ง๋ฉด, ๊ณ ๊ฐ์ ์ ๊ณต์๋ก๋ถํฐ ๋ณด์์ ๋ฐ๋๋ค.
๋ชจ๋ ์๋น์ค์ SLA๊ฐ ์์ด์ผ ํ๋ ๊ฒ์ ์๋์ง๋ง, SLO๋ ์์ด์ผ ํ๋ค. SLO์ ๊ธฐ์ค์ SLA๋ณด๋ค ๋์์ผํ๋ค.