2009-07-08 4 views
3

Учитывая, что во время развертывания я не знаю, в какой системе будет работать мой код, как написать контрольный показатель производительности, который использует потенциал системы в качестве критерия.Как выполнить модульный тест для относительной производительности?

Я имею в виду, что если система способна запускать кусок кода 1000 раз в секунду, я бы хотел, чтобы тест обеспечивал максимально возможное приближение к 1000. Если он может делать только 500, то это тот показатель, который я бы хотел сравнить с ним.

Если это помогает сделать ответ более конкретным, я использую JUnit4.

спасибо.

+0

Почему вы хотите единичный тест вместо профайлера? – Paco

+0

Другие дали четкие точки, что единичный тест не является испытанием на производительность, а скорее тестом «ожидаемой функциональности». Профилирование профилей - это то, что вам нужно - они не простые звери. – STW

ответ

5

тест означает, что у вас есть годен/не годен порог. Для теста производительности это означает слишком медленное, и вы терпите неудачу, достаточно быстро и проходите. Если вы терпите неудачу, вы начинаете делать доработки.

Если вы не можете потерпеть неудачу, тогда вы сравниваете, а не тестируете.

Когда вы говорите о том, что «система способна работать», вы должны определить «способный». Вы можете использовать любое большое количество тестов производительности оборудования.Whetstone, Dhrystone и т. Д. Популярны. Или, возможно, у вас есть приложение, интенсивно использующее базу данных, тогда вы можете посмотреть тест TPC. Или, возможно, у вас есть сетевое приложение и вы хотите использовать netperf. Или приложение с графическим интерфейсом и хотите использовать какой-то графический тест.

Любой из них дает вам какое-то измерение «возможности». Выберите один или несколько. Они все хороши. Не менее спорным. Не менее предвзятый к вашему конкуренту и далеко от вас.

Как только вы запустите тест, вы можете запустить свое программное обеспечение и посмотреть, что на самом деле делает система.

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

Имея достаточное количество данных из достаточного количества ящиков с достаточно разными конфигурациями, вы в конечном итоге сможете разработать производительность модель, в которой говорится: «Учитывая это оборудование, программное обеспечение, параметры настройки и конфигурацию, я ожидаю, что мое программное обеспечение сделает [X] транзакций в секунду». Это твердое определение «способный».

После того, как у вас есть эта модель, вы можете сравнить свое программное обеспечение с номером возможности. Пока у вас нет полной модели, вы действительно не знаете, какие системы даже способны запускать кусок кода 1000 раз в секунду.

+0

В основном вам нужен какой-то уже существующий тест, чтобы сравнить результаты теста. –

6

Я бы не использовал модульное тестирование для тестов производительности по нескольким причинам.

Во-первых, модульные тесты не должны иметь зависимости от окружающей системы/кода. Тесты производительности сильно зависят от оборудования/ОС, поэтому трудно получить единые меры, которые будут использоваться на рабочих станциях разработчика, сервере сборки и т. Д.

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

+0

Хороший ответ, а не мой вопрос, но хороший ответ, тем не менее. –

+0

Прокомментируйте это при голосовании. –

0

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

Все, что я делаю, это график времени обработки дельты, который был проведен в последнее время. Обратите внимание, процессорное время не в режиме реального времени. Фактическое значение не имеет большого значения - важно то, насколько оно изменилось.

Если я совершу изменение алгоритма, который значительно изменил время выполнения теста, я могу легко увеличить его до определенного набора изменений, вызвавшего его. То, что мне действительно волнует, - это эти точки интереса - не обязательно абсолютные ценности. В системе реального времени довольно много компромиссов, и они не всегда могут быть представлены в тестовой структуре как простой сравнительный.

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

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

В моем случае это может фактически загружать прошивку в DSP, дистанционно управлять им, читая ответ от последовательного порта или не видя ответа, потому что он разбился!

--jeffk ++

2

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

import static org.junit.Assert.*; 
import org.junit.Test; 

package com.stackoverflow.samples.tests { 

    @Test 
    public void doStuffRuns500TimesPerSecond() { 
     long maximumRunningTime = 1000; 
     long currentRunningTime = 0; 
     int iterations = 0; 

     do { 
      long startTime = System.getTimeMillis(); 

      // do stuff 

      currentRunningTime += System.getTimeMillis() - startTime; 
      iterations++; 
     } 
     while (currentRunningTime <= maximumRunningTime); 

     assertEquals(500, iterations); 
    } 
} 
Смежные вопросы