Тестирование производительности с использованием классов

В этом примере показано, как создать тест эффективности и регрессионный тест для fprintf функция.

Тест эффективности

Рассмотрите следующий модульный (регрессионный) тест. Этот тест можно запустить как тест эффективности, используя runperf('fprintfTest') вместо runtests('fprintfTest').

classdef fprintfTest < matlab.unittest.TestCase
    properties
        file
        fid
    end
    methods(TestMethodSetup)
        function openFile(testCase)
            testCase.file = tempname;
            testCase.fid = fopen(testCase.file,'w');
            testCase.assertNotEqual(testCase.fid,-1,'IO Problem')
            
            testCase.addTeardown(@delete,testCase.file);
            testCase.addTeardown(@fclose,testCase.fid);
        end
    end
    
    methods(Test)
        function testPrintingToFile(testCase)
            textToWrite = repmat('abcdef',1,5000000);
            fprintf(testCase.fid,'%s',textToWrite);
            testCase.verifyEqual(fileread(testCase.file),textToWrite)
        end
        
        function testBytesToFile(testCase)
            textToWrite = repmat('tests_',1,5000000);
            nbytes = fprintf(testCase.fid,'%s',textToWrite);
            testCase.verifyEqual(nbytes,length(textToWrite))
        end
    end
end

Измеренное время не включает время открытия и закрытия файла или значения, потому что эти действия происходят внутри TestMethodSetup блок, а не внутри Test блок. Однако измеренное время включает время для выполнения верификаций. Лучшая практика состоит в том, чтобы измерить более точный контур эффективности.

Создайте тест эффективности в файле, fprintfTest.m, в текущей рабочей папке. Этот тест похож на регрессионный тест со следующими модификациями:

  • Тест наследует от matlab.perftest.TestCase вместо matlab.unittest.TestCase.

  • Тест вызывает startMeasuring и stopMeasuring методы для создания контура вокруг fprintf вызов функции.

classdef fprintfTest < matlab.perftest.TestCase
    properties
        file
        fid
    end
    methods(TestMethodSetup)
        function openFile(testCase)
            testCase.file = tempname;
            testCase.fid = fopen(testCase.file,'w');
            testCase.assertNotEqual(testCase.fid,-1,'IO Problem')
            
            testCase.addTeardown(@delete,testCase.file);
            testCase.addTeardown(@fclose,testCase.fid);
        end
    end
    
    methods(Test)
        function testPrintingToFile(testCase)
            textToWrite = repmat('abcdef',1,5000000);
            
            testCase.startMeasuring();
            fprintf(testCase.fid,'%s',textToWrite);
            testCase.stopMeasuring();
            
            testCase.verifyEqual(fileread(testCase.file),textToWrite)
        end
        
        function testBytesToFile(testCase)
            textToWrite = repmat('tests_',1,5000000);
            
            testCase.startMeasuring();
            nbytes = fprintf(testCase.fid,'%s',textToWrite);
            testCase.stopMeasuring();
            
            testCase.verifyEqual(nbytes,length(textToWrite))
        end
    end
end

Измеренное время для этого теста эффективности включает только вызов на fprintf, и среда тестирования все еще оценивает проверки.

Запуск теста эффективности

Запустите тест эффективности. В зависимости от вашей системы, вы можете увидеть предупреждения о том, что среда тестирования эффективности запустила тест максимальное количество раз, но не достигла 0.05 относительный запас ошибки с 0.95 доверительный уровень.

results = runperf('fprintfTest')
Running fprintfTest
.......... .......... .
Done fprintfTest
__________


results = 

  1×2 TimeResult array with properties:

    Name
    Valid
    Samples
    TestActivity

Totals:
   2 Valid, 0 Invalid.
   4.1417 seconds testing time.

The results переменная является 1-by- 2 TimeResultмассив. Каждый элемент массива соответствует одному из тестов, определенных в тестовом файле.

Отобразите результаты тестирования

Отобразите результаты измерений для первого теста. Ваши результаты могут варьироваться.

results(1)
ans = 

  TimeResult with properties:

            Name: 'fprintfTest/testPrintingToFile'
           Valid: 1
         Samples: [4×7 table]
    TestActivity: [8×12 table]

Totals:
   1 Valid, 0 Invalid.
   2.7124 seconds testing time.

На что указывает размер TestActivity свойство, собранная среда тестирования эффективности 8 измерения. Это число включает 4 измерения для прогрева кода. The Samples свойство исключает измерения разогрева.

Отображение выборочных измерений для первого теста.

results(1).Samples
ans =

  4×7 table

                 Name                 MeasuredTime         Timestamp             Host        Platform                     Version                                 RunIdentifier            
    ______________________________    ____________    ____________________    ___________    ________    __________________________________________    ____________________________________

    fprintfTest/testPrintingToFile      0.067729      24-Jun-2019 16:22:09    MY-HOSTNAME     win64      9.7.0.1141441 (R2019b) Prerelease Update 2    62991eef-5570-47b0-ade5-b8a805245e8f
    fprintfTest/testPrintingToFile      0.067513      24-Jun-2019 16:22:09    MY-HOSTNAME     win64      9.7.0.1141441 (R2019b) Prerelease Update 2    62991eef-5570-47b0-ade5-b8a805245e8f
    fprintfTest/testPrintingToFile      0.068737      24-Jun-2019 16:22:09    MY-HOSTNAME     win64      9.7.0.1141441 (R2019b) Prerelease Update 2    62991eef-5570-47b0-ade5-b8a805245e8f
    fprintfTest/testPrintingToFile      0.068576      24-Jun-2019 16:22:10    MY-HOSTNAME     win64      9.7.0.1141441 (R2019b) Prerelease Update 2    62991eef-5570-47b0-ade5-b8a805245e8f

Вычисление статистики для единичного тестового элемента

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

sampleTimes = results(1).Samples.MeasuredTime;
meanTest = mean(sampleTimes)
meanTest =

    0.0681

Вычисление статистики для всех тестовых элементов

Определите среднее время для всех тестовых элементов. The fprintfTest тест включает два различных метода. Сравните время для каждого метода (тестового элемента).

Поскольку среда тестирования эффективности возвращает Samples таблица для каждого тестового элемента, объедините все эти таблицы в одну таблицу. Затем сгруппируйте строки по тестовым элементам Name, и вычислите среднее MeasuredTime для каждой группы.

fullTable = vertcat(results.Samples);
summaryStats = varfun(@mean,fullTable,...
    'InputVariables','MeasuredTime','GroupingVariables','Name')
summaryStats =

  2×3 table

                 Name                 GroupCount    mean_MeasuredTime
    ______________________________    __________    _________________

    fprintfTest/testPrintingToFile        4             0.068139     
    fprintfTest/testBytesToFile           9             0.071595     

Оба метода тестирования записывают одинаковый объем данных в файл. Поэтому некоторое различие между средними значениями связано с вызовом fprintf функция с выходным аргументом.

Изменение статистических целей и повторные тесты

Измените статистические цели, определенные в runperf функция путем построения и выполнения временного эксперимента. Создайте временной эксперимент с измерениями, которые достигают среднего значения выборки с помощью 3% относительный запас ошибки в 97% доверительный уровень. Сбор 4 измерения прогрева и до 16 измерения проб.

Создайте явный тестовый набор.

suite = testsuite('fprintfTest');

Создайте временной эксперимент с переменным количеством выборочных измерений и запустите тесты.

import matlab.perftest.TimeExperiment
experiment = TimeExperiment.limitingSamplingError('NumWarmups',4,...
    'MaxSamples',16,'RelativeMarginOfError',0.03,'ConfidenceLevel',0.97);
resultsTE = run(experiment,suite);
Running fprintfTest
.......... ..........Warning: Target Relative Margin of Error not met after running the MaxSamples for fprintfTest/testPrintingToFile. 
 ........
Done fprintfTest
__________

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

Вычислите статистику для всех тестовых элементов.

fullTableTE = vertcat(resultsTE.Samples);
summaryStatsTE = varfun(@mean,fullTableTE,...
    'InputVariables','MeasuredTime','GroupingVariables','Name')
summaryStatsTE =

  2×3 table

                 Name                 GroupCount    mean_MeasuredTime
    ______________________________    __________    _________________

    fprintfTest/testPrintingToFile        16            0.069482     
    fprintfTest/testBytesToFile            4            0.067902     

Увеличьте максимальное количество выборок до 32 и повторите временной эксперимент.

experiment = TimeExperiment.limitingSamplingError('NumWarmups',4,...
    'MaxSamples',32,'RelativeMarginOfError',0.03,'ConfidenceLevel',0.97);
resultsTE = run(experiment,suite);
Running fprintfTest
.......... ......
Done fprintfTest
__________

Вычислите статистику для всех тестовых элементов.

fullTableTE = vertcat(resultsTE.Samples);
summaryStatsTE = varfun(@mean,fullTableTE,...
    'InputVariables','MeasuredTime','GroupingVariables','Name')
summaryStatsTE =

  2×3 table

                 Name                 GroupCount    mean_MeasuredTime
    ______________________________    __________    _________________

    fprintfTest/testPrintingToFile        4             0.067228     
    fprintfTest/testBytesToFile           4             0.067766     

Среда тестирования достигает статистических целей для обоих тестов с 4 выборки.

Измерение затрат в первый раз

Запуск нового MATLAB® сеанс. Новый сеанс гарантирует, что MATLAB не запустил код, содержащийся в ваших тестах.

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

Создайте явный тестовый набор. Поскольку вы измеряете первую стоимость функции, запустите один тест. Чтобы запустить несколько тестов, сохраните результаты и запустите новый сеанс работы с MATLAB между тестами.

suite = testsuite('fprintfTest/testPrintingToFile');

Создайте и запустите временной эксперимент.

import matlab.perftest.TimeExperiment
experiment = TimeExperiment.withFixedSampleSize(1);
results = run(experiment,suite);
Running fprintfTest
.
Done fprintfTest
__________

Отображение результатов. Наблюдайте за TestActivity таблица для обеспечения отсутствия выборок прогрева.

fullTable = results.TestActivity
fullTable =

  1×12 table

                 Name                 Passed    Failed    Incomplete    MeasuredTime    Objective         Timestamp             Host        Platform                     Version                                 TestResult                          RunIdentifier            
    ______________________________    ______    ______    __________    ____________    _________    ____________________    ___________    ________    __________________________________________    ________________________________    ____________________________________

    fprintfTest/testPrintingToFile    true      false       false         0.071754       sample      24-Jun-2019 16:31:27    MY-HOSTNAME     win64      9.7.0.1141441 (R2019b) Prerelease Update 2    [1×1 matlab.unittest.TestResult]    045394eb-e722-4241-8da2-1d17a97ac90a

Среда тестирования эффективности собирает по одной выборке для каждого теста.

См. также

| | | | |