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

Этот пример показывает, как создать тест производительности и регрессионный тест на функцию 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 = 

  1x2 MeasurementResult array with properties:

    Name
    Valid
    Samples
    TestActivity

Totals:
   2 Valid, 0 Invalid.

  Переменная results 1x2  массив MeasurementResult. Каждый элемент в массиве соответствует одному из тестов, заданных в тестовом файле.

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

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

results(1)
ans = 

  MeasurementResult with properties:

            Name: 'fprintfTest/testPrintingToFile'
           Valid: 1
         Samples: [10x7 table]
    TestActivity: [14x12 table]

Totals:
   1 Valid, 0 Invalid.

Как обозначено размером  свойства TestActivity, среда тестирования производительности собрала 14 измерений. Этот номер включает 4 измерения, чтобы нагреть код.  Свойство Samples исключает измерения прогрева.

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

results(1).Samples
ans = 

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

    fprintfTest/testPrintingToFile    0.067772        02-Jan-2016 18:24:52    MY-HOSTNAME    win64       9.0.0.320924 (R2016a)    9b6a0d5c-5fe7-4d26-8479-222792127ebc
    fprintfTest/testPrintingToFile    0.085359        02-Jan-2016 18:24:53    MY-HOSTNAME    win64       9.0.0.320924 (R2016a)    9b6a0d5c-5fe7-4d26-8479-222792127ebc
    fprintfTest/testPrintingToFile    0.075863        02-Jan-2016 18:24:53    MY-HOSTNAME    win64       9.0.0.320924 (R2016a)    9b6a0d5c-5fe7-4d26-8479-222792127ebc
    fprintfTest/testPrintingToFile    0.068161        02-Jan-2016 18:24:53    MY-HOSTNAME    win64       9.0.0.320924 (R2016a)    9b6a0d5c-5fe7-4d26-8479-222792127ebc
    fprintfTest/testPrintingToFile    0.067606        02-Jan-2016 18:24:53    MY-HOSTNAME    win64       9.0.0.320924 (R2016a)    9b6a0d5c-5fe7-4d26-8479-222792127ebc
    fprintfTest/testPrintingToFile    0.073692        02-Jan-2016 18:24:54    MY-HOSTNAME    win64       9.0.0.320924 (R2016a)    9b6a0d5c-5fe7-4d26-8479-222792127ebc
    fprintfTest/testPrintingToFile    0.070815        02-Jan-2016 18:24:54    MY-HOSTNAME    win64       9.0.0.320924 (R2016a)    9b6a0d5c-5fe7-4d26-8479-222792127ebc
    fprintfTest/testPrintingToFile    0.067791        02-Jan-2016 18:24:54    MY-HOSTNAME    win64       9.0.0.320924 (R2016a)    9b6a0d5c-5fe7-4d26-8479-222792127ebc
    fprintfTest/testPrintingToFile    0.077599        02-Jan-2016 18:24:54    MY-HOSTNAME    win64       9.0.0.320924 (R2016a)    9b6a0d5c-5fe7-4d26-8479-222792127ebc
    fprintfTest/testPrintingToFile     0.07438        02-Jan-2016 18:24:55    MY-HOSTNAME    win64       9.0.0.320924 (R2016a)    9b6a0d5c-5fe7-4d26-8479-222792127ebc

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

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

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

    0.0729

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

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

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

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

                 Name                 GroupCount    mean_MeasuredTime
    ______________________________    __________    _________________

    fprintfTest/testPrintingToFile    10            0.072904         
    fprintfTest/testBytesToFile       27            0.079338         

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

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

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

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

suite = testsuite('fprintfTest');

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

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

..........
..........
..........
..........Warning: The target Relative Margin of Error was not met after running the MaxSamples for
fprintfTest/testBytesToFile.

Done fprintfTest
__________

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

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

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

                 Name                 GroupCount    mean_MeasuredTime
    ______________________________    __________    _________________

    fprintfTest/testPrintingToFile    32            0.081782         
    fprintfTest/testBytesToFile       32            0.076378  

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

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

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

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

                 Name                 GroupCount    mean_MeasuredTime
    ______________________________    __________    _________________

    fprintfTest/testPrintingToFile    55             0.07783         
    fprintfTest/testBytesToFile       53            0.079008         

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

Мера в первый раз стоимость

Запустите новый сеанс 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 = 

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

    fprintfTest/testPrintingToFile    true      false     false         0.065501        sample       06-Jan-2016 09:53:44    MY-HOSTNAME    win64       9.0.0.323070 (R2016a)    [1x1 matlab.unittest.TestResult]    e0fe27aa-3224-46d1-a05a-542e9b8d9edb

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

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

| | | |

Была ли эта тема полезной?