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