Java에서 배열을 반복하는 가장 빠른 방법 : loop ariable vs 명령문 [Duplication

StackOverflow https://stackoverflow.com/questions/1006395

  •  06-07-2019
  •  | 
  •  

문제

이 질문은 이미 여기에 답이 있습니다.

Java에서는 구식 방식의 배열을 통해 반복하는 것이 더 빠릅니다.

for (int i = 0; i < a.length; i++)
    f(a[i]);

또는 더 간결한 형태를 사용하여

for (Foo foo : a)
    f(foo);

Arraylist의 경우 답이 동일합니까?

물론 방대한 적용 코드의 경우, 대답은 식별 할 수있는 차이가 없으므로 더 간결한 형태를 가독성에 사용해야한다는 것입니다. 그러나 제가보고있는 맥락은 수십억 번 수행 해야하는 작업을 수행 해야하는 중대한 기술 계산이므로 작은 속도 차이조차도 중요 할 수 있습니다.

도움이 되었습니까?

해결책

배열을 통해 반복되는 경우, 고리를 위해 향상된 루프는 어쨌든 배열 액세스를 사용합니다.

예를 들어이 코드를 고려하십시오.

public static void main(String[] args)
{
    for (String x : args)
    {
        System.out.println(x);
    }
}

분해 될 때 javap -c Test 우리는 ( main 방법):

public static void main(java.lang.String[]);
  Code:
   0:   aload_0
   1:   astore_1
   2:   aload_1
   3:   arraylength
   4:   istore_2
   5:   iconst_0
   6:   istore_3
   7:   iload_3
   8:   iload_2
   9:   if_icmpge   31
   12:  aload_1
   13:  iload_3
   14:  aaload
   15:  astore  4
   17:  getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   20:  aload   4
   22:  invokevirtual   #3; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   25:  iinc    3, 1
   28:  goto    7
   31:  return

이제 명시적인 배열 액세스를 사용하려면 변경하십시오.

public static void main(String[] args)
{
    for (int i = 0; i < args.length; i++)
    {
        System.out.println(args[i]);
    }
}

이것은 다음과 컴파일합니다.

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   aload_0
   4:   arraylength
   5:   if_icmpge   23
   8:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   11:  aload_0
   12:  iload_1
   13:  aaload
   14:  invokevirtual   #3; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   17:  iinc    1, 1
   20:  goto    2
   23:  return

루프를 위해 향상된 설정 코드가 조금 더 많지만 기본적으로 동일한 작업을 수행하고 있습니다. 반복자가 관여하지 않습니다. 또한, 나는 그들이 더 유사한 코드로 Jitted를 얻을 것으로 기대합니다.

제안 : 정말로 그것이 큰 차이를 만들 수 있다고 생각한다면 항상 루프의 본문이 절대적으로 미미하다면) 실제 응용 프로그램으로 벤치마킹해야합니다. 그것이 중요한 상황입니다.

다른 팁

이것은 경기장에 정사각형입니다 미세 최적화. 정말 중요하지 않습니다. 스타일 적으로 나는 다른 것에 대한 루프 카운터가 필요하지 않으면 더 간결하기 때문에 항상 두 번째를 선호합니다. 그리고 그게 이런 종류의 미세 최적화보다 훨씬 중요합니다: 가독성.

즉, 배열 목록의 경우 큰 차이는 없지만 링크 사전 목록은 두 번째로 훨씬 더 효율적일 것입니다.

측정하십시오. 모든 성능 질문에 대한 답은 VM 버전, 프로세서, 메모리 속도, 캐시 등에 따라 달라질 수 있으므로 특정 플랫폼에 대해 측정해야합니다.

개인적으로 나는 의도가 더 분명하기 때문에 두 번째 변형을 선호합니다. 성능이 문제가되면 어쨌든 나중에 최적화 할 수 있습니다. 해당 코드가 실제로 전체 응용 프로그램의 성능에 중요하다면 실제로 중요합니다.

Linkedlist의 경우 :

for(ClassOfElement element : listOfElements) {
  System.out.println(element.getValue());
}

이전에 답했습니다.

루프와 각각의 루프 사이의 성능 차이가 있습니까?

배열 또는 RandomAccess 컬렉션에서는 다음을 통해 속도가 약간 증가 할 수 있습니다.

List<Object> list = new ArrayList<Object>();

for (int i=0, d=list.size(); i<d; i++) {
    something(list.get(i));
}

그러나 나는 일반적으로 걱정하지 않을 것입니다. 이와 같은 최적화는 코드와 0.1% 이상 차이를 만들지 않습니다. Java를 호출해보십시오 -prof 코드가 실제로 시간을 보내는 위치를 확인합니다.

더 빠르게 포크 조인 프레임 워크의 평행 배열을 사용하는 것이 더 빠릅니다 (충분히 큰 데이터 세트가있는 경우).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top