πŸ’» Programming/Java

[Java] μŠ€νŠΈλ¦Όμ„ μ΄μš©ν•œ μ†Œμˆ˜ κ΅¬ν•˜κΈ°

μΌ€μ΄μΉ˜ 2022. 10. 28. 14:21

μš”μ¦˜ μ΄νŽ™ν‹°λΈŒ μžλ°” Third μ—λ””μ…˜ 책을 동넀 λ„μ„œκ΄€μ—μ„œ λŒ€μ—¬ν•΄μ„œ μ½κ³ μžˆμŠ΅λ‹ˆλ‹€.

슀트림 병렬화에 λŒ€ν•œ 글을 읽닀가 μ†Œμˆ˜κ΅¬ν•˜λŠ” λ‘œμ§μ„ 슀트림으둜 μž‘μ„±ν•œ 뢀뢄을 λ³΄κ²Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

μ†Œμˆ˜κ΅¬ν•˜κΈ° λ‘œμ§μ€ 이직쀀비 ν•  λ•Œλ‚˜ λ‹€μ‹œ λ“€μ—¬λ‹€λ³Όλ§Œν•œκ±°λΌ μ˜€λž˜μ „μ— for-loop 둜 κ΅¬ν˜„ν•΄λ³Έ κΈ°μ–΅λ§Œ μžˆλ‹€λ³΄λ‹ˆ μ‹ μ„ ν•˜κ²Œ λŠκ»΄μ‘Œλ„€μš”.

아직도 λ§Žμ€ λΈ”λ‘œκ·Έλ“€μ—μ„œ for-loopλ₯Ό μ΄μš©ν•œ λ°©λ²•λ“€λ§Œ 많이 μ†Œκ°œν•˜κ³  μžˆκΈ°λ„ ν•˜κ³ ν•΄μ„œ ν¬μŠ€νŒ… 주제둜 μ‚Όμ•„λ΄€μŠ΅λ‹ˆλ‹€. 

개인적인 기둝도 ν• κ²Έ...

책을 읽고 μƒˆλ‘œ μ•Œκ²Œλœ 뢀뢄은 μŠ€νŠΈλ¦Όμ— λŒ€ν•œ 뢀뢄도 μžˆμ§€λ§Œ 이미 BigInteger ν΄λž˜μŠ€μ— isProbablePrime μ΄λž€ λ©”μ„œλ“œκ°€ μžˆμ—ˆλ‹€λŠ” κ²λ‹ˆλ‹€..

 

μ•„λž˜λŠ” νŠΉμ • 숫자 n κΉŒμ§€ μ†Œμˆ˜κ°€ λͺ‡ κ°œμΈμ§€λ₯Ό 좜λ ₯ν•˜κ³ , κ·Έ λͺ©λ‘λ„ 좜λ ₯ν•˜λŠ” 것을 ν…ŒμŠ€νŠΈν•œ μ½”λ“œμž…λ‹ˆλ‹€.

public static void main(String[] args) {
    int n = (int) Math.pow(10, 8);
    // n κΉŒμ§€μ˜ 수 쀑에 μ†Œμˆ˜μ˜ 개수 좜λ ₯ν•˜κΈ°
    long cnt = LongStream.rangeClosed(2, n)
    	    .parallel()
            .mapToObj(BigInteger::valueOf)
            .filter(i -> i.isProbablePrime(50))
            .count();
    System.out.println(cnt);

    // n κΉŒμ§€μ˜ 수 쀑에 μ†Œμˆ˜ λͺ©λ‘ 좜λ ₯ν•˜κΈ°
    System.out.println(LongStream.rangeClosed(2, n)
            .mapToObj(BigInteger::valueOf)
            .filter(i -> i.isProbablePrime(50))
            .collect(Collectors.toList()));
}

LongStream을 μ΄μš©ν•˜μ—¬ 숫자의 λ²”μœ„λ₯Ό μ •ν•˜κ³  mapToObj λ₯Ό μ΄μš©ν•˜μ—¬ BigInteger둜 λ³€ν˜•ν•œλ’€ BigInteger.isProbablePrime(int certainty) λ©”μ„œλ“œλ₯Ό ν•„ν„°λ‘œ μ „λ‹¬ν•˜μ—¬ μ†Œμˆ˜λ₯Ό κ΅¬ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

BigInteger.isProbablePrime(int certainty) λ©”μ„œλ“œλŠ” μ†Œμˆ˜λ₯Ό κ΅¬ν•˜κΈ°μœ„ν•΄ λ‚΄λΆ€μ μœΌλ‘œ λ°€λŸ¬-라빈(Miller-Rabin) ν…ŒμŠ€νŠΈμ™€ λ£¨μΉ΄μŠ€-레머(Lucas-Lehmer) ν…ŒμŠ€νŠΈλ₯Ό μ‚¬μš©ν•˜κ³  μžˆκ³ μš”. μ—¬κΈ°μ„œ μ‚¬μš©λœ λ°€λŸ¬λΌλΉˆ ν…ŒμŠ€νŠΈλŠ” DSA(Digital Signiture Algorithm) μŠ€νŽ™ (NIST FIPS 186-2)을 기반으둜 ν–ˆλ‹€κ³  ν•©λ‹ˆλ‹€. 이 μŠ€νŽ™μ€ 파일둜 μ²¨λΆ€ν•˜λ‹ˆ κ΄€μ‹¬μžˆμœΌμ‹  뢄듀은 λ‹€μš΄λ°›μ•„ 보셔도 될 것 κ°™λ„€μš”. 

 

fips186-2.pdf
0.35MB

 

참고둜 .parallel() 은 μŠ€νŠΈλ¦Όμ—μ„œ μ‚¬μš©ν•  λ•Œ 맀우 주의λ₯Ό μš”ν•˜λŠ” κΈ°λŠ₯μž…λ‹ˆλ‹€. μ±…μ—μ„œλŠ” μ΄λ ‡κ²Œ μ–˜κΈ°ν•©λ‹ˆλ‹€. Stream.iterate λ₯Ό 데이터 μ†ŒμŠ€λ‘œ μ΄μš©ν•˜κ±°λ‚˜ 쀑간 μ—°μ‚°μœΌλ‘œ limit 을 μ‚¬μš©ν•˜λŠ” 슀트림 νŒŒμ΄ν”„λΌμΈμ—μ„œλŠ” parallel을 μ΄μš©ν•œ μ„±λŠ₯κ°œμ„ μ„ κΈ°λŒ€ν•  수 μ—†μœΌλ©° 였히렀 μ•ˆμ’‹μ•„μ§ˆ μˆ˜λ„ μžˆλ‹€κ³  말이죠. μ‹€μ œλ‘œ μš΄μ˜ν™˜κ²½μ—μ„œ 저것 λ•Œλ¬Έμ— μ΄μŠˆκ°€ λ°œμƒν•œ 적도 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. κ·Έλƒ₯ λ¬΄ν•œλ£¨ν”„μ— λΉ μ§„κ²ƒμ²˜λŸΌ μ“°λ ˆλ“œ ν•˜λ‚˜κ°€ 먹톡이 λ˜μ–΄λ²„λ¦¬λ”κ΅°μš”. μŠ€νŠΈλ¦Όμ—μ„œ 병렬연산에 μ ν•©ν•œ 적은 reduce, min, max, count, sum λ“±μ˜ 연산이며, collect처럼 κ°€λ³€μΆ•μ†Œλ₯Ό μˆ˜ν–‰ν•˜λŠ” λ©”μ„œλ“œλŠ” 병렬연산에 μ ν•©ν•˜μ§€ μ•Šλ‹€κ³  ν•©λ‹ˆλ‹€. μ°Έκ³ ν•˜μ‹œκΈ° λ°”λžλ‹ˆλ‹€.