В этом примере показано, как создать тест эффективности и регрессионный тест для 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.
The results
переменная является 1
-by- 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
измерения для прогрева кода. The 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
Определите среднее время для всех тестовых элементов. The 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