Java Word Count ์ต์ ํ๋ก ์ฒ๋ฆฌ ์๋ 7๋ฐฐ ํฅ์ ๋ฐ ๋ฉ๋ชจ๋ฆฌ ํจ์จ ๊ทน๋ํ
From Strings to Silicon: How I Optimized a Java Word Count by 7X ๐
AI ์์ฝ
Context
2์ต ๊ฐ์ ๋จ์ด๊ฐ ํฌํจ๋ 1.5GB ํ ์คํธ ํ์ผ์ ๋น๋์๋ฅผ ๊ณ์ฐํ๋ ์์คํ ์ค๊ณ. ์ด๊ธฐ Java NIO ๊ธฐ๋ฐ์ ๋จ์ ๊ตฌํ์ฒด๋ ์ ์ฒด ํ์ผ์ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋ํ๋ ๋ฐฉ์์ผ๋ก ์ธํ ๊ณผ๋ํ ๋ฉ๋ชจ๋ฆฌ ์ ์ ์ ๋จ์ผ ์ค๋ ๋ ์ฒ๋ฆฌ์ ๋ฎ์ ์ฑ๋ฅ ํ๊ณ๋ฅผ ๋ณด์.
Technical Solution
- Files.lines() Stream ๋์ ์ ํตํ ํ์ผ ์ ์ฒด ๋ก๋ ๋ฐฉ์ ์ ๊ฑฐ ๋ฐ ๋ฉ๋ชจ๋ฆฌ footprint ์ต์ํ
- 8๊ฐ ๊ณ ์ ์ค๋ ๋ ํ ๊ธฐ๋ฐ์ Divide and Conquer ์ ๋ต ์ ์ฉ์ผ๋ก CPU ์ฝ์ด ํ์ฉ๋ ๊ทน๋ํ
- Thread-local aggregation ๊ตฌ์กฐ ์ค๊ณ๋ฅผ ํตํ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ๊ฒฝํฉ(Contention) ๋ฐ Lock ์ค๋ฒํค๋ ์ ๊ฑฐ
- String.split()์ ๋ด๋ถ ์ ๊ทํํ์ ์ฒ๋ฆฌ ๋น์ฉ์ ์ค์ด๊ธฐ ์ํ ๋ฌธ์์ด ํ ๋น ์ต์ ํ ์๋
- MappedByteBuffer ๋ฐ FileChannel ํ์ฉ์ผ๋ก OS ๋ ๋ฒจ์ Zero-copy์ ๊ฐ๊น์ด ํ์ผ I/O ์ฒ๋ฆฌ
- ํ๋์จ์ด ์บ์(L1/L2) ํจ์จ์ ๊ณ ๋ คํ ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์ ๋ฐ ๋ฐ์ดํฐ ์ก์ธ์ค ํจํด ์ต์ ํ
์ค์ฒ ํฌ์ธํธ
1. ๋์ฉ๋ ํ์ผ ์ฒ๋ฆฌ ์ ์ ์ฒด ๋ก๋ ๋์ Stream์ด๋ MappedByteBuffer ๊ฒํ
2. ๋ฉํฐ์ค๋ ๋ฉ ์ค๊ณ ์ Lock ๊ธฐ๋ฐ ๊ณต์ ์์๋ณด๋ค Shared-Nothing ๊ตฌ์กฐ์ Thread-local ์ ์ฅ์ ์ฐ์ ๊ณ ๋ ค
3. ์ฑ๋ฅ ๋ณ๋ชฉ ์ง์ ํ์ ์ ์ํด POC ๊ธฐ๋ฐ์ baseline ์ธก์ ํ ์ ์ง์ ์ต์ ํ ์ํ
4. ์ ๊ทํํ์ ๊ธฐ๋ฐ์ split() ๋ฑ ๊ณ ๋น์ฉ ๋ฌธ์์ด ์ฐ์ฐ์ ๋์ฒด ๋ฐฉ์ ํ์