Java 8 스트림을 연습하기 위해 다음 중첩 루프를 Java 8 스트림 API로 변환하려고 시도했습니다. 내가 더 빨리 될 것으로 예상 나의 코어 I5 760스트림 및 성능이있는 Java 8 중첩 루프
public static int digitSum(BigInteger x)
{
int sum = 0;
for(char c: x.toString().toCharArray()) {sum+=Integer.valueOf(c+"");}
return sum;
}
@Test public void solve()
{
int max = 0;
for(int i=1;i<100;i++)
for(int j=1;j<100;j++)
max = Math.max(max,digitSum(BigInteger.valueOf(i).pow(j)));
System.out.println(max);
}
내 솔루션에 ~ 0.135s (< 100 B, A)는^B의 가장 큰 숫자의 합을 계산하고 소요 paralellism 실제로했다의 때문에 합니다 (parallel()
없이 0.19 초) 0.25s :
int max = IntStream.range(1,100).parallel()
.map(i -> IntStream.range(1, 100)
.map(j->digitSum(BigInteger.valueOf(i).pow(j)))
.max().getAsInt()).max().getAsInt();
내 질문에
- 내가 변환 오른쪽을하거나 더 나은 방법 t이 한 o 네스트 된 루프를 스트림 계산으로 변환 하시겠습니까?
- 왜 스트림 변형이 이전 버전보다 훨씬 느립니까?
- 왜 parallel() 문이 실제로 시간을 0.19 초에서 0.25 초로 늘렸습니까?
마이크로 벤치 마크는 깨지기 쉽고 병렬 처리는 큰 문제에 대해서만 가치가 있지만 CPU의 경우 0.1 초조차도 영원하다는 것을 알고 있습니다. 맞습니까?
업데이트 I 이클립스 케플러의 JUnit 4에서는 프레임 워크 측정
(이것은 테스트를 수행하는데 걸리는 시간을 나타낸다). < 1,000 대신 100 B A 용
내 결과 :
- 전통적인 루프 186s
- 순차 스트림 193s
- 병렬 스트림 55S
업데이트 2 sum+=Integer.valueOf(c+"");
교체 sum+= c - '0';
(감사합니다 Peter!) 10 초 전체를 면도했습니다. 평행 방법의 onds, 45s에 그것을 가져 오는. 성능에 큰 영향을 줄 것으로 기대하지 않았습니다!
또한 CPU 코어의 수 (이 경우 4 개)에 대한 병렬 처리를 줄이면 시간이 44.8 초로 단축되었으므로 (예 : a와 b = 0이 추가되었지만 성능에 많은 영향을 미치지 않습니다.) :
int max = IntStream.range(0, 3).parallel().
.map(m -> IntStream.range(0,250)
.map(i -> IntStream.range(1, 1000)
.map(j->.digitSum(BigInteger.valueOf(250*m+i).pow(j)))
.max().getAsInt()).max().getAsInt()).max().getAsInt();
어떻게 측정합니까? 적절한주의를 기울이지 않으면 마이크로 벤치 마크 결과가 오도 될 수 있습니다. – assylias
'sum + = Integer.valueOf (c + "");'를'sum + = c - '0'; '으로 대체하는 것이 훨씬 빠르다. –
FWIW 당신은'digitSum'의 루프를'CharSequence.chars()'메소드를 사용하여 스트림으로 대체 할 수 있습니다. 그것은 char 배열을 할당하는 것을 피한다. –