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