2013-09-29 1 views
0

타사 라이브러리에서 데이터를 가져 오는 시간에 민감한 응용 프로그램이 있습니다. 내 애플리케이션에 적합한 인터페이스로 오브젝트를 래핑하는 것과 관련된 성능 적중률은 무엇입니까?오브젝트를 래핑 할 때 실제 오버 헤드는 얼마입니까?

참고 : 여기에 답변을 게시하고 있습니다 (Q & A 스타일). 틀렸을 경우 나에게 수정하십시오.

+0

이는 포장의 종류에 따라 달라집니다. – Raedwald

답변

1

이 있어요 - 여기에 결과 모든 실제로 일치하지 않는, 여기에서 실제로 느려질 것을 풀어왔다이다 간접비가있는 일부 오버 헤드가 있지만 측정하기가 어렵습니다. OP의 벤치 마크는 반복 당 약 4 ns가 소요되는 반면, 광산은 약 1 ns (가장 빠른 실험을 위해)가 필요합니다. 이것은 가상 호출 오버 헤드와 함께 대부분 ArrayList, Iteratorcycle의 오버 헤드를 측정하고 있음을 의미합니다.

측정 할 오버 헤드가 너무 작기 때문에 배열을 사용하고 내부 루프를 추가하거나 액세스 할 때 마스킹을 사용해야합니다.

benchmarkresults은 인터페이스와 간접 지정을 사용하여 측정 가능한 오버 헤드가 있음을 보여줍니다. 이 오버 헤드는 아마도 20 %에서 50 %까지 다양합니다. 그러나 중요한 부분은의 20-50 % 입니다. 이것은 코드를 실행하는 것 외에 특별히 제작 된 벤치 마크의 일부분입니다. 현실적인 조각 코드에서 상대 오버 헤드는 10 배, 100 배 또는 1000 배 낮아집니다.

아주 기본적인 작업과 빠른 작업을 수행하는 고성능 라이브러리를 디자인하지 않는 한 잊어 버리십시오. 간접 사용과 인터페이스를 마음대로 사용하고 좋은 디자인에 집중하십시오. 성능이 중요하더라도 더 많이 얻을 수있는 다른 장소가있을 것입니다.

WrappingBenchmark

+0

나는 오버 헤드가 절대적인 것보다는 백분율 이상으로 중요하다고 생각한다. 마지막 단락에서 이유를 설명합니다. 제 답변에 동의 해 주셔서 감사합니다. 내 응용 프로그램에서 성능이 매우 중요하지만 중요한 성능 손실이 걱정없이 데이터 피드를 래핑하지 않아서 벽을 상대로 머리를 때리는 것을 멈출 수 있다는 것을 알게되어 기쁩니다. – durron597

0

몇 달 동안 수업을 진행 하려다가 오늘 시험을보기로 결심했습니다. 어떤 오버 헤드라도 추가하지 않는 것 같습니다.

0% Scenario{vm=java, trial=0, benchmark=Unwrapped} 3.96 ns; ?=0.02 ns @ 3 trials 
33% Scenario{vm=java, trial=0, benchmark=Copy} 3.93 ns; ?=0.01 ns @ 3 trials 
67% Scenario{vm=java, trial=0, benchmark=Backing} 3.94 ns; ?=0.01 ns @ 3 trials 

benchmark ns linear runtime 
Unwrapped 3.96 ============================== 
    Copy 3.93 ============================= 
    Backing 3.94 ============================= 

vm: java 
trial: 0 

소스 코드 (캘리퍼스 0.5 RC1, 구아바 2.0 이상) :

import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.List; 
import java.util.Random; 

import com.google.caliper.Runner; 
import com.google.caliper.SimpleBenchmark; 
import com.google.common.collect.Iterables; 

public class WrapperTest { 
    public static class Unwrapped { 
     private int inner; 

     public Unwrapped(int inner) { 
      this.inner = inner; 
     } 

     public int getInner() { 
      return inner; 
     } 
    } 

    public static interface Outer { 
     public int getOuter(); 
    } 

    public static class CopyOuter implements Outer { 
     private int outer; 

     public CopyOuter(int outer) { 
      this.outer = outer; 
     } 

     public int getOuter() { 
      return outer; 
     } 
    } 

    public static class BackingOuter implements Outer { 
     private Unwrapped inner; 

     public BackingOuter(Unwrapped inner) { 
      this.inner = inner; 
     } 

     public int getOuter() { 
      return inner.getInner(); 
     } 
    } 

    public static class TestBenchmark extends SimpleBenchmark { 
     private Iterable<Unwrapped> cycle; 

     @Override 
     protected void setUp() { 
      List<Unwrapped> backing = new ArrayList<Unwrapped>(16384); 
      Random r = new Random(); 
      for(int i = 0; i < 16384; i++) { 
       backing.add(new Unwrapped(Math.abs(r.nextInt()))); 
      } 
      cycle = Iterables.cycle(backing); 
     } 

     public long timeUnwrapped(int reps) { 
      long total = 0; 
      Iterator<Unwrapped> iter = cycle.iterator(); 
      for(int i = 0; i < reps; i++) { 
       total += iter.next().getInner(); 
      } 
      return total; 
     } 

     public long timeCopy(int reps) { 
      long total = 0; 
      Iterator<Unwrapped> iter = cycle.iterator(); 
      for(int i = 0; i < reps; i++) { 
       total += new CopyOuter(iter.next().getInner()).getOuter(); 
      } 
      return total; 
     } 

     public long timeBacking(int reps) { 
      long total = 0; 
      Iterator<Unwrapped> iter = cycle.iterator(); 
      for(int i = 0; i < reps; i++) { 
       total += new BackingOuter(iter.next()).getOuter(); 
      } 
      return total; 
     } 
    } 

    public static void main(String[] args) { 
     Runner.main(TestBenchmark.class, new String[0]); 
    } 
} 
+0

나는 벤치 마크가 너무 정확해서 3.93이 3.96보다 실제로 빠르다고 말할 수 없다고 생각한다. 나는 측정 오류가 일반적으로 5 % 정도이고 아마도 '주기'와 같은 것이 실행 시간을 지배하기 때문에 귀하의 경우에 더 많은 것 같아요. 또한 마이크로 벤치 마크에서의 성능과 실제 애플리케이션에서의 성능 간의 차이가 더 커질 수 있습니다. – maaartinus

+1

여러 번 실행되는 사소한 메서드를 래핑하지 않는 한 래핑하는 데 신경 쓰지 않을 것입니다. 나는 JIT가 비용의 상당 부분을 최적화 할 수 있다고 생각한다. – maaartinus

+0

@maaartinus 답장을 보내 주셔서 감사합니다. 네, 3.93이 3.96과 거의 같다고 생각합니다. 주기적인 iterable 생성은'setUp'에서 일어나므로 실행 시간에는 영향을 미치지 않습니다. 나는 단지 IndexOutOfBounds 예외가 없도록하기 위해 그것을했다. – durron597

관련 문제