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

В этом примере показано, как создать тест производительности и регрессионный тест на 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.

results переменной является 1- 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 измерения, чтобы нагреть код. 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

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

Определите среднее время для всех тестовых элементов. 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

Среда тестирования производительности собирает одну выборку для каждого теста.

Смотрите также

| | | | |