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