2013-09-29 3 views
0

У меня есть приложение, зависящее от времени, которое получает данные из сторонней библиотеки. Каким будет результат производительности, связанный с переносом их объектов на более подходящие интерфейсы для моего приложения?Каковы фактические накладные расходы от обертывания объектов?

Примечание: Я отправляю ответ здесь (Q & Стиль), но если это неправильно, пожалуйста, исправьте меня!

+0

Это будет зависеть от вида завертывания. – Raedwald

ответ

1

Там это некоторые накладные расходы с косвенностью, но их трудно измерить. Ориентир OP занял около 4 нс на итерацию, в то время как мне требуется около 1 нс (для самого быстрого эксперимента). Это означает, что они измеряли главным образом накладные расходы ArrayList, Iterator и cycle, вероятно, вместе с накладными расходами на виртуальные вызовы.

Накладные расходы, которые необходимо измерить, настолько малы, что вам нужно использовать массивы и либо добавить внутренний цикл, либо использовать маскировку для доступа к ним.

results из моего benchmark показывают, что есть накладные расходы на использование как интерфейса, так и косвенного. Эти накладные расходы колеблются от 20% до 50%, что очень похоже. Однако важная часть составляет 20-50% того, что. Это часть специально созданного теста, ничего не делающего, кроме осуществления кода. В любом реалистичном фрагменте кода относительные накладные расходы будут в десять, сотни или тысячи раз ниже.

Итак, если вы не разрабатываете высокоэффективную библиотеку, выполняющую очень простые и быстрые операции, просто забудьте ее. Используйте косвенную ориентацию и интерфейсы по своему усмотрению и сконцентрируйтесь на хорошем дизайне. Даже если производительность важна, возможно, есть другие места, где вы можете получить больше.

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% в целом и, возможно, больше в вашем случае, так как такие вещи, как 'cycle', вероятно, доминируют во время выполнения. Более того, разница между производительностью в микрообъекте и в реальном приложении может быть еще больше. – maaartinus

+1

Меня не интересует стоимость обертывания, если вы не выполняете тривиальные методы, выполняемые много раз. Я думаю, что JIT может оптимизировать некоторые из этих затрат. – maaartinus

+0

@maaartinus Спасибо за ваш ответ. Да, я считаю 3,93 примерно равным 3,96. Создание циклического итерации происходит в 'setUp', поэтому оно не влияет на время выполнения. Я просто сделал это, чтобы исключить исключение «IndexOutOfBounds». – durron597

Смежные вопросы