Этот пример показывает, как создать тест производительности и регрессионный тест на функцию 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
Среда тестирования производительности собирает одну выборку для каждого теста.
matlab.perftest. TestCase
| matlab.perftest. TimeExperiment
| matlab.unittest.measurement. MeasurementResult
| runperf
| testsuite