2016-02-03 4 views
1

Я строю тестовую упряжь в java и пытаюсь сравнить производительность и латентность двух парсеров. Разбирает данные, полученные от одного живого, одного канала. У меня нет контроля над фидом, и у меня нет «имитированного фида» для издевательских данных, поэтому для сравнения яблок с яблоками я бы хотел, чтобы мои анализы проводились как можно раньше. Я новичок в java и threading, поэтому не уверен, что это лучший подход. Моя идея состояла в том, чтобы открутить 2 резьбы:Как выполнить одновременно две операции?

SomeFeed feed = new SomeFeed(); 

Thread thread1 = new Thread() { 
    public void run() { 
    parser1.parseFeed(feed); 
    } 
}; 
Thread thread2 = new Thread() { 
    public void run() { 
    parse2.parseFeed(feed); 
    } 
}; 
thread1.start(); 
thread2.start(); 

Будет ли поток работать таким образом примерно синхронно? Или есть лучший подход?

Благодаря

+0

Если вы можете одновременно запускать два парсера из одного и того же канала, вы также можете просто запускать их последовательно. Запуск одновременно вводит коробку pandoras с несогласованностью. Но я подозреваю, что это не сработает, потому что фид не поддержит его. – Durandal

+0

Мы не решаемся запускать их последовательно, потому что выход фида может резко и непредсказуемо измениться. –

+0

Это решение неправильной проблемы. Вы должны задать вопрос о том, как вы могли бы изменить свой дизайн, чтобы предоставить способ для издевательства данных (есть несколько хорошо установленных и простых методов для этого) вместо того, чтобы пытаться решить проблему, которая возникает рядом с невозможной. Это не только значительно повысит надежность ваших тестов производительности, но и позволит вам проверять ваши парсеры, что всегда хорошо. – Voo

ответ

1

Имея два потока работать точно параллельно не то, что вы можете реально контролировать. Но если вы заботитесь о начиная их в то же время (почти) вы можете использовать CyclicBarrier (взято из here):

// We want to start just 2 threads at the same time, but let's control that 
// timing from the main thread. That's why we have 3 "parties" instead of 2. 
final CyclicBarrier gate = new CyclicBarrier(3); 

Thread t1 = new Thread(){ 
    public void run(){ 
     gate.await(); 
     //do stuff  
    }}; 
Thread t2 = new Thread(){ 
    public void run(){ 
     gate.await(); 
     //do stuff  
    }}; 

t1.start(); 
t2.start(); 

// At this point, t1 and t2 are blocking on the gate. 
// Since we gave "3" as the argument, gate is not opened yet. 
// Now if we block on the gate from the main thread, it will open 
// and all threads will start to do stuff! 

gate.await(); 
System.out.println("all threads started"); 

Это поможет вам ближе всего к запуская их одновременно.

+0

Прохладный, это конечно помогает. Любая идея о том, как «близко» к параллельным потокам в java обычно запускается? От этого зависит, например, моя архитектура процессора? –

+0

Это зависит от количества ядер. Если у вас есть 1, то вы можете в значительной степени * банк * на нем, что он не будет работать хорошо. Но с более чем 1 он будет довольно разумно параллельным. – Idos

+0

Спасибо. Кроме того, предположим, что операция run() заканчивается на t1, но все еще работает на t2. Есть ли способ узнать, когда оба закончили? И еще, чтобы возобновить операцию? Я хочу измерить это возможно примерно 20 раз. CyclicBarrier звучит так, как будто он работает в цикле. Хотя, я думаю, я мог бы просто создать цикл for. –

1

Это один из способов делать вещи. Другим способом является внедрение интерфейса Runnable.

public class SomeFeed implements Runnable { 

    public void run() { 
     System.out.println("Hello from a thread!"); 
    } 

    public static void main(String args[]) { 
     (new Thread(new SomeFeed())).start(); 
    } 

} 

Новый подход заключается в использовании ThreadPool.

Это способ, которым Вы могли бы создать пул и выполнить код

ExecutorService pool = Executors.newFixedThreadPool(2); 

for(int i = 0; i < 2; i++){ 
    pool.submit(new SomeFeed()); 


} 

Убедитесь SomeFeed Реализует Callable интерфейс.

Более подробную информацию можно найти here

+0

Спасибо, я прочитаю с информацией, которую вы связали. –

0

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

Сохраните подачу в сторону, чтобы стать вашим справочным набором данных для обоих тестов.

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

И вы также должны сделать более 1500 прогонов, чтобы иметь справедливую меру времени avg, которое принимает подпрограмма (1500 вызовов метода - это порог для компиляции JIT Hotspot, которая ускоряет код). Кроме того, постарайтесь, чтобы код работал не менее 30 секунд, чтобы также можно было усреднить потенциальные помехи для вариантов ОС и дисков.

И если вы заметили паузу GC (всегда включаете журнал gc во время тестов), тогда вам нужно запустить тест либо в большем объеме памяти, чтобы избежать полного gc (например, использовать -Xmx2G), либо выполнить тест так часто, что число полных ГХ довольно равномерно в обоих парсерах.

Во всяком случае, злоупотребления памяти и, следовательно, время GC также являются фактором производительности, чтобы судить о худшем парсере.

+0

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

+0

PS, почему работает одновременно плохо? Я беспокоюсь о разном времени обработки парсера, а не о абсолютном времени обработки. Так что не будет работать одновременно, по крайней мере, позвольте мне сравнить производительность в аналогичных условиях (хотя эти условия отражают мои реальные условия выполнения)? –

+1

просто потому, что 1 парсер всасывает процессор, память (возможно, даже nw и i/o), что несправедливо по отношению к другому парсеру, наоборот ... нет? У вас нет гарантии, что есть 2 децитированных процессора, 2 выделенных диска, 2 выделенных «всего», чтобы установить честный тест. 1-й парсер замедлит ваш второй парсер и наоборот, но ОС может предоставить больше времени и ввода/вывода тяжелому парсеру, что делает его слишком хорошим, а анализатор света выглядит плохо. ОС слишком умны и определенно не линейны. – user2023577

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