Этот пример показывает, как создать тест производительности и регрессионный тест на функцию 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. Переменная results 1x2 массив MeasurementResult. Каждый элемент в массиве соответствует одному из тестов, заданных в тестовом файле.
Отобразите результаты измерения для первого теста. Ваши результаты могут отличаться.
results(1)
ans =
TimeResult with properties:
Name: 'fprintfTest/testPrintingToFile'
Valid: 1
Samples: [4×7 table]
TestActivity: [8×12 table]
Totals:
1 Valid, 0 Invalid.Как обозначено размером свойства TestActivity, среда тестирования производительности собрала 14 измерений. Этот номер включает 4 измерения, чтобы нагреть код. Свойство Samples исключает измерения прогрева.
Отобразите демонстрационные измерения для первого теста.
results(1).Samples
ans =
4×7 table
Name MeasuredTime Timestamp Host Platform Version RunIdentifier
______________________________ ____________ ____________________ _______ ________ ________________________________ ____________________________________
fprintfTest/testPrintingToFile 0.090988 26-Oct-2018 14:09:10 MY-HOSTNAME win64 9.6.0.979037 (R2019a) Prerelease 84305243-69b9-4104-a50e-459ce687ceb9
fprintfTest/testPrintingToFile 0.092055 26-Oct-2018 14:09:10 MY-HOSTNAME win64 9.6.0.979037 (R2019a) Prerelease 84305243-69b9-4104-a50e-459ce687ceb9
fprintfTest/testPrintingToFile 0.0918 26-Oct-2018 14:09:10 MY-HOSTNAME win64 9.6.0.979037 (R2019a) Prerelease 84305243-69b9-4104-a50e-459ce687ceb9
fprintfTest/testPrintingToFile 0.085175 26-Oct-2018 14:09:11 MY-HOSTNAME win64 9.6.0.979037 (R2019a) Prerelease 84305243-69b9-4104-a50e-459ceОтобразитесь среднее значение измерило время для первого теста. Чтобы исключить данные, собранные в выполнениях прогрева, используйте значения в поле Samples.
sampleTimes = results(1).Samples.MeasuredTime; meanTest = mean(sampleTimes)
meanTest =
0.0900Определите среднее время для всех тестовых элементов. Тест 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.090004
fprintfTest/testBytesToFile 4 0.08558 Оба метода тестирования пишут тот же объем данных в файл. Поэтому часть различия между средними значениями приписана вызыванию функции fprintf с выходным аргументом.
Измените статистические цели, заданные функцией runperf путем построения и выполнения эксперимента времени. Создайте эксперимент времени с измерениями, которые достигают демонстрационного среднего значения с 3%-м относительным пределом погрешности на 97%-м доверительном уровне. Соберите восемь измерений прогрева и до 32 демонстрационных измерений.
Создайте явный тестовый набор.
suite = testsuite('fprintfTest');Создайте эксперимент времени с переменным количеством демонстрационных измерений и запустите тесты.
import matlab.perftest.TimeExperiment experiment = TimeExperiment.limitingSamplingError('NumWarmups',8,... '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 7 0.08887
fprintfTest/testBytesToFile 6 0.08836 Увеличьте максимальное число выборок к 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 =
2×3 table
Name GroupCount mean_MeasuredTime
______________________________ __________ _________________
fprintfTest/testPrintingToFile 6 0.088188
fprintfTest/testBytesToFile 4 0.092162 Среда тестирования достигает статистических целей для обоих тестов приблизительно в 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 =
1×12 table
Name Passed Failed Incomplete MeasuredTime Objective Timestamp Host Platform Version TestResult RunIdentifier
______________________________ ______ ______ __________ ____________ _________ ____________________ _______ ________ ________________________________ ________________________________ ____________________________________
fprintfTest/testPrintingToFile true false false 0.09189 sample 26-Oct-2018 14:18:46 MY-HOSTNAME win64 9.6.0.979037 (R2019a) Prerelease [1x1 matlab.unittest.TestResult] 36d0b490-d2cc-4c8c-bac7-395b5976d638
Среда тестирования производительности собирает одну выборку для каждого теста.
matlab.perftest.TestCase | matlab.perftest.TimeExperiment | matlab.perftest.TimeResult | matlab.unittest.measurement.DefaultMeasurementResult | runperf | testsuite