exponenta event banner

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

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

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

См. также

| | | | |