Amenable
Amenable's Blog
Amenable
  • λΆ„λ₯˜ 전체보기 (189)
    • πŸ“‚ JAVA (87)
      • μ΄νŽ™ν‹°λΈŒ μžλ°” (65)
      • μ£Όμš” κ°œλ… (22)
    • πŸ“‚ 개발 μ„œμ  (22)
      • μ‹€μš©μ£Όμ˜ ν”„λ‘œκ·Έλž˜λ¨Έ (1)
      • 객체지ν–₯의 사싀과 μ˜€ν•΄ (2)
      • 클린 μ½”λ“œ (8)
      • ν•¨κ»˜ 자라기 (1)
      • 그림으둜 λ°°μš°λŠ” HTTP&Network Basic (10)
    • πŸ“‚ λ°μ΄ν„°λ² μ΄μŠ€ (8)
      • κ°œλ… (8)
      • λ¬Έμ œν’€μ΄ (0)
    • πŸ“‚ λ„€νŠΈμ›Œν¬ (14)
      • κ°œλ… (6)
      • 성곡과 μ‹€νŒ¨λ₯Ό κ²°μ •ν•˜λŠ” 1%의 λ„€νŠΈμ›Œν¬ 원리 (8)
    • πŸ“‚ μŠ€ν”„λ§ (13)
      • κΈ°λ³Έ κ°œλ… (13)
    • πŸ“‚ WEB (5)
    • πŸ“‚ 자료ꡬ쑰 (12)
      • κ°œλ… (2)
      • μ •λ ¬ (8)
      • 트리 (2)
    • πŸ“‚ μ•Œκ³ λ¦¬μ¦˜ (10)
      • μ΅œμ†Œμ‹ μž₯트리 (2)
      • μ΅œλ‹¨ 경둜 (2)
      • λ¬Έμžμ—΄ (2)
      • ETC (4)
    • πŸ“‚ μ•Œκ³ λ¦¬μ¦˜_λ¬Έμ œν’€μ΄ (4)
      • BOJ_λ°±μ€€ (4)
    • πŸ“‚ ν”„λ‘œκ·Έλž˜λ° (3)
    • πŸ“‚ DevOps (2)
      • 배포 (2)
    • πŸ“‚ ν›„κΈ° (8)
      • μš°μ•„ν•œ ν…Œν¬μ½”μŠ€(ν”„λ¦¬μ½”μŠ€) (4)
      • 2023λ…„ (3)
      • 2024λ…„ (1)
    • πŸ“‚ 회고 (1)
      • 2023λ…„ (1)

λΈ”λ‘œκ·Έ 메뉴

  • πŸš€ GitHub

ν‹°μŠ€ν† λ¦¬

hELLO Β· Designed By μ •μƒμš°.
Amenable

Amenable's Blog

슀트림 λ³‘λ ¬ν™”λŠ” μ£Όμ˜ν•΄μ„œ μ μš©ν•˜λΌ - [7μž₯. λžŒλ‹€μ™€ 슀트림(μ•„μ΄ν…œ48)]
πŸ“‚ JAVA/μ΄νŽ™ν‹°λΈŒ μžλ°”

슀트림 λ³‘λ ¬ν™”λŠ” μ£Όμ˜ν•΄μ„œ μ μš©ν•˜λΌ - [7μž₯. λžŒλ‹€μ™€ 슀트림(μ•„μ΄ν…œ48)]

2023. 12. 10. 11:45

πŸ“™ 1. μžλ°”μ˜ λ™μ‹œμ„± ν”„λ‘œκ·Έλž˜λ°

  μžλ°”λŠ” λ™μ‹œμ„± ν”„λ‘œκ·Έλž˜λ° μΈ‘λ©΄μ—μ„œ 항상 μ•žμ„œκ°”λ‹€.

  • 처음 릴리슀된 1996λ…„
    μŠ€λ ˆλ“œ, 동기화, wait/notify 지원
  • μžλ°” 5
    λ™μ‹œμ„± μ»¬λ ‰μ…˜μΈ java.util.concurrent  λΌμ΄λΈŒλŸ¬λ¦¬μ™€ μ‹€ν–‰μž(Executor) ν”„λ ˆμž„μ›Œν¬ 지원
  • μžλ°” 7
    κ³ μ„±λŠ₯ 병렬 λΆ„ν•΄(parallel decom-position) ν”„λ ˆμž„μ›Œν¬μΈ 포크-쑰인(fork-join) νŒ¨ν‚€μ§€ μΆ”κ°€
  • μžλ°” 8
    parallel λ©”μ„œλ“œλ§Œ ν•œ 번 ν˜ΈμΆœν•˜λ©΄ νŒŒμ΄ν”„λΌμΈμ„ 병렬 μ‹€ν–‰ν•  수 μžˆλŠ” 슀트림 지원

  이처럼 μžλ°”λ‘œ λ™μ‹œμ„± ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜κΈ°κ°€ 점점 μ‰¬μ›Œμ§€κ³  μžˆλ‹€. ν•˜μ§€λ§Œ, λ™μ‹œμ„± ν”„λ‘œκ·Έλž˜λ°μ„ ν•  λ•ŒλŠ” μ•ˆμ „μ„±(safety)κ³Ό 응닡 κ°€λŠ₯(liveness) μƒνƒœλ₯Ό μœ μ§€ν•˜κΈ° μœ„ν•΄ 애써야 ν•œλ‹€. 병렬 μŠ€νŠΈλ¦Ό νŒŒμ΄ν”„라인 ν”„λ‘œκ·Έλž˜λ°μ—μ„œλ„ λ§ˆμ°¬κ°€μ§€λ‹€.

 

πŸ“™ 2. 성곡적인 슀트림 νŒŒμ΄ν”„λΌμΈ 병렬화

  슀트림 νŒŒμ΄ν”„λΌμΈ λ³‘λ ¬ν™”μ˜ 효과λ₯Ό λ¨Όμ € μ•Œμ•„λ³΄μž.

  λ‹€μŒκ³Ό 같이 n보닀 μž‘κ±°λ‚˜ 같은 μ†Œμˆ˜μ˜ 개수λ₯Ό κ³„μ‚°ν•˜λŠ” ν•¨μˆ˜κ°€ μžˆλ‹€κ³  ν•΄λ³΄μž. 병렬화λ₯Ό ν•˜μ§€ μ•Šμ€ κ²½μš°μ™€ 병렬화λ₯Ό ν•œ κ²½μš°λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

// 병렬화λ₯Ό ν•˜μ§€ μ•Šμ€ 경우
static long pi(long n) {
    return LongStream.rangeClosed(2, n)
            .mapToObj(BigInteger::valueOf)
            .filter(i -> i.isProbablePrime(50))
            .count();
}

// 병렬화λ₯Ό ν•œ 경우
static long pi(long n) {
    return LongStream.rangeClosed(2, n)
            .parallel()
            .mapToObj(BigInteger::valueOf)
            .filter(i -> i.isProbablePrime(50))
            .count();
}

  ν•΄λ‹Ή μ½”λ“œλ₯Ό μ΄μš©ν•˜μ—¬ 10^7(10_000_000)을 κ³„μ‚°ν•˜μ˜€μ„ λ•Œ, 병렬화 μ „μ—λŠ” 26μ΄ˆκ°€ κ±Έλ Έκ³  병렬화 ν›„μ—λŠ” 10μ΄ˆκ°€ κ±Έλ Έλ‹€.

즉, λ³‘λ ¬ν™”λ₯Ό ν†΅ν•΄ 2.6배의 μ„±λŠ₯ ν–₯상을 λ³Έ κ²ƒμ΄λ‹€.

 

πŸ“™ 3. 잘λͺ»λœ 슀트림 νŒŒμ΄ν”„λΌμΈ 병렬화

  λ‹€μŒμ€ 슀트림 νŒŒμ΄ν”„λΌμΈ 병렬화λ₯Ό 잘 λͺ» μ‚¬μš©ν•œ 예λ₯Ό μ‚΄νŽ΄λ³΄μž.

  μ˜ˆμ‹œλŠ” μ•„μ΄ν…œ 45(링크)μ—μ„œ λ‹€λ£¨μ—ˆλ˜ λ©”λ₯΄μ„Ό μ†Œμˆ˜λ₯Ό μƒμ„±ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ΄λ‹€.

private static final int COUNT = 20;

public static void main(String[] args) {

    primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE))
            .filter(mersenne -> mersenne.isProbablePrime(50))
            .limit(COUNT)
            .forEach(System.out::println);
}

  이 μ½”λ“œλ„ 병렬화λ₯Ό ν•œ κ²½μš°κ°€ 병렬화λ₯Ό ν•˜κΈ° 전보닀 더 λΉ¨λΌμ‘Œμ„κΉŒ?

  μ•„λ‹ˆλ‹€. 병렬화λ₯Ό ν•˜κ²Œ λœλ‹€λ©΄ 이 경우 아무것도 좜λ ₯ν•˜μ§€ λͺ»ν•˜λ©΄μ„œ μ‘λ‹΅λΆˆκ°€(liveness) μƒνƒœκ°€ λœλ‹€. κ·Έ μ΄μœ λŠ” 슀트림 λΌμ΄λΈŒλŸ¬λ¦¬κ°€ 이 νŒŒμ΄ν”„λΌμΈμ„ λ³‘λ ¬ν™”ν•˜λŠ” 방법을 μ°Ύμ•„λ‚΄μ§€ λͺ»ν–ˆκΈ° λ•Œλ¬Έμ΄λ‹€.

  데이터 μ†ŒμŠ€κ°€ Stream.iterate κ±°λ‚˜ 쀑간 μ—°μ‚°μœΌλ‘œ limit을 μ“°λ©΄ νŒŒμ΄ν”„λΌμΈ λ³‘λ ¬ν™”λ‘œλŠ” μ„±λŠ₯ κ°œμ„ μ„ κΈ°λŒ€ν•  수 μ—†λ‹€. νŒŒμ΄ν”„λΌμΈ λ³‘λ ¬ν™”λŠ” limit을 λ‹€λ£° λ•Œ CPU μ½”μ–΄κ°€ λ‚¨λŠ”λ‹€λ©΄ μ›μ†Œλ₯Ό λͺ‡ 개 더 μ²˜λ¦¬ν•œ ν›„ μ œν•œλœ 개수 μ΄ν›„μ˜ κ²°κ³Όλ₯Ό 버렀도 μ•„λ¬΄λŸ° ν•΄κ°€ μ—†λ‹€κ³  κ°€μ •ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. λ‹€μŒ μ†Œμˆ˜λ₯Ό μ°ΎλŠ” λ° κ±Έλ¦¬λŠ” μ‹œκ°„이 μ΄μ „ μ†Œμˆ˜λ₯Ό μ°ΎλŠ” 데 κ±Έλ¦¬λŠ” μ‹œκ°„보닀 λ” λ§Žμ΄ κ±°λ¦¬κΈ° λ•Œλ¬Έμ— λ³‘λ ¬ν™”κ°€ μ œ κΈ°λŠ₯을 λ°œνœ˜ν•˜μ§€ λͺ»ν•œ κ²ƒμ΄λ‹€.

 

πŸ“™ 4. 슀트림 νŒŒμ΄ν”„λΌμΈ 병렬화λ₯Ό μ μš©ν•˜λŠ” κΈ°μ€€

  λŒ€μ²΄λ‘œ 슀트림 μ†ŒμŠ€κ°€ ArrayList, HashMap, HashSet, ConcurrentHashMap의 μΈμŠ€ν„΄μŠ€ κ±°λ‚˜ λ°°μ—΄, int λ²”μœ„, long λ²”μœ„μΌ λ•Œ λ³‘λ ¬ν™”μ˜ νš¨κ³Όκ°€ κ°€μž₯ μ’‹λ‹€. 이 μžλ£Œκ΅¬μ‘°λ“€μ€ λͺ¨λ‘ 데이터λ₯Ό μ›ν•˜λŠ” 크기둜 μ •ν™•ν•˜κ³  μ†μ‰½κ²Œ λ‚˜λˆŒ 수 μžˆμ–΄μ„œ 일을 λ‹€μˆ˜μ˜ μŠ€λ ˆλ“œμ— λΆ„λ°°ν•˜κΈ° μ’‹λ‹€λŠ” νŠΉμ§•μ΄ μžˆλ‹€.

  λ˜ν•œ, 이 μžλ£Œκ΅¬μ‘°λ“€μ€ μ›μ†Œλ“€μ„ 순차적으둜 μ‹€ν–‰ν•  λ•Œ μ°Έμ‘° μ§€μ—­μ„±(locality of reference)이 λ›°μ–΄λ‚˜κΈ° λ•Œλ¬Έμ— λ‹€λŸ‰μ˜ 데이터λ₯Ό μ²˜λ¦¬ν•˜λŠ” 벌크 연산을 병렬화할 λ•Œ 이점이 μžˆλ‹€.

 

  슀트림 νŒŒμ΄ν”„λΌμΈμ˜ 쒅단 μ—°μ‚°μ˜ λ™μž‘ 방식 μ—­μ‹œ 병렬 μˆ˜ν–‰ νš¨μœ¨μ— 영ν–₯을 μ€€λ‹€. 쒅단 μ—°μ‚°μ—μ„œ μˆ˜ν–‰ν•˜λŠ” μž‘μ—…λŸ‰μ΄ νŒŒμ΄ν”„λΌμΈ 전체 μž‘μ—…μ—μ„œ 상당 비쀑을 μ°¨μ§€ν•˜λ©΄μ„œ 순차적인 연산이라면 νŒŒμ΄ν”„λΌμΈ 병렬 μˆ˜ν–‰μ˜ νš¨κ³ΌλŠ” μ œν•œλ  μˆ˜λ°–μ— μ—†λ‹€.

  • νŒŒμ΄ν”„λΌμΈμ—μ„œ λ§Œλ“€μ–΄μ§„ λͺ¨λ“  μ›μ†Œλ₯Ό ν•˜λ‚˜λ‘œ ν•©μΉ˜λŠ” μž‘μ—…μΈ μΆ•μ†Œ(reduction)κ°€ 병렬화에 μ ν•©ν•œ 쒅단 연산이닀. (ex. min, max, count, sum)
  • 쑰건에 맞으면 λ°”λ‘œ λ°˜ν™˜λ˜λŠ” λ©”μ„œλ“œλ„ 병렬화에 μ ν•©ν•˜λ‹€. (ex. anyMatch, allMatch, noneMatch)
  • μ»¬λ ‰μ…˜μ„ ν•©μΉ˜λŠ” 뢀담이 큰 κ°€λ³€ μΆ•μ†Œ(mutable reduction)λŠ” 병렬화에 μ ν•©ν•˜μ§€ μ•Šλ‹€.

 

  μŠ€νŠΈλ¦Όμ„ 잘λͺ» λ³‘λ ¬ν™”ν•˜λ©΄ (응닡 λΆˆκ°€λ₯Ό 포함해) μ„±λŠ₯이 λ‚˜λΉ μ§ˆ 뿐만 μ•„λ‹ˆλΌ κ²°κ³Ό μžμ²΄κ°€ 잘λͺ»λ˜κ±°λ‚˜ μ˜ˆμƒ λͺ»ν•œ λ™μž‘μ΄ λ°œμƒν•  수 μžˆλ‹€. λ”°λΌμ„œ, 계산도 μ˜¬λ°”λ₯΄κ³  μ„±λŠ₯도 빨라질 κ±°λΌλŠ” ν™•μ‹  μ—†μ΄λŠ” 슀트림 νŒŒμ΄ν”„λΌμΈ λ³‘λ ¬ν™”λŠ” μ‹œλ„μ‘°μ°¨ ν•˜μ§€ 말자. μŠ€νŠΈλ¦Όμ„ 잘λͺ» λ³‘λ ¬ν™”ν•˜λ©΄ ν”„λ‘œκ·Έλž¨μ„ μ˜€λ™μž‘ν•˜κ²Œ ν•˜κ±°λ‚˜ μ„±λŠ₯을 κΈ‰κ²©νžˆ λ–¨μ–΄λœ¨λ¦°λ‹€.

  λ˜ν•œ, 병렬화λ₯Ό ν•˜λŠ” 게 λ‚«λ‹€κ³  νŒλ‹¨μ΄ 되면, 운영 μ‹œμŠ€ν…œκ³Ό ν‘μ‚¬ν•œ ν™˜κ²½μ—μ„œ ν…ŒμŠ€νŠΈλ₯Ό μ§„ν–‰ν•˜λ„λ‘ ν•˜μž.

 

 

ν•΄λ‹Ή 글은 Joshua Bloch λ‹˜μ˜ 'Effective Java 3/E'λ₯Ό μ°Έκ³ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

 

'πŸ“‚ JAVA > μ΄νŽ™ν‹°λΈŒ μžλ°”' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

μ μ‹œμ— 방어적 볡사본을 λ§Œλ“€λΌ - [8μž₯. λ©”μ„œλ“œ(μ•„μ΄ν…œ50)]  (0) 2023.12.10
λ§€κ°œλ³€μˆ˜κ°€ μœ νš¨ν•œμ§€ κ²€μ‚¬ν•˜λΌ - [8μž₯. λ©”μ„œλ“œ(μ•„μ΄ν…œ49)]  (0) 2023.12.10
λ°˜ν™˜ νƒ€μž…μœΌλ‘œλŠ” μŠ€νŠΈλ¦Όλ³΄λ‹€ μ»¬λ ‰μ…˜μ΄ λ‚«λ‹€ - [7μž₯. λžŒλ‹€μ™€ 슀트림(μ•„μ΄ν…œ47)]  (1) 2023.12.09
μŠ€νŠΈλ¦Όμ—μ„œλŠ” λΆ€μž‘μš© μ—†λŠ” ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λΌ - [7μž₯. λžŒλ‹€μ™€ 슀트림(μ•„μ΄ν…œ46)]  (0) 2023.12.09
μŠ€νŠΈλ¦Όμ€ μ£Όμ˜ν•΄μ„œ μ‚¬μš©ν•˜λΌ - [7μž₯. λžŒλ‹€μ™€ 슀트림(μ•„μ΄ν…œ45)]  (0) 2023.12.09
    'πŸ“‚ JAVA/μ΄νŽ™ν‹°λΈŒ μžλ°”' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€
    • μ μ‹œμ— 방어적 볡사본을 λ§Œλ“€λΌ - [8μž₯. λ©”μ„œλ“œ(μ•„μ΄ν…œ50)]
    • λ§€κ°œλ³€μˆ˜κ°€ μœ νš¨ν•œμ§€ κ²€μ‚¬ν•˜λΌ - [8μž₯. λ©”μ„œλ“œ(μ•„μ΄ν…œ49)]
    • λ°˜ν™˜ νƒ€μž…μœΌλ‘œλŠ” μŠ€νŠΈλ¦Όλ³΄λ‹€ μ»¬λ ‰μ…˜μ΄ λ‚«λ‹€ - [7μž₯. λžŒλ‹€μ™€ 슀트림(μ•„μ΄ν…œ47)]
    • μŠ€νŠΈλ¦Όμ—μ„œλŠ” λΆ€μž‘μš© μ—†λŠ” ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λΌ - [7μž₯. λžŒλ‹€μ™€ 슀트림(μ•„μ΄ν…œ46)]
    Amenable
    Amenable
    CS, μžλ°”, 자료ꡬ쑰, μ•Œκ³ λ¦¬μ¦˜, μŠ€ν”„λ§, μŠ€ν”„λ§ λΆ€νŠΈμ— ν•΄λ‹Ήν•˜λŠ” κ°œλ°œμ— κ΄€ν•œ λ‚΄μš©μ„ κ³΅μœ ν•©λ‹ˆλ‹€.

    ν‹°μŠ€ν† λ¦¬νˆ΄λ°”