クラスを使用したパフォーマンスのテスト
この例では、関数 fprintf
のクラスベースのパフォーマンス テストと回帰テストを作成して実行する方法を説明します。
パフォーマンス テストの記述
次の単体 (回帰) テストについて考えてみます。このテストは、runtests("fprintfTest")
の代わりに runperf("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
測定時間にはファイルの開閉またはアサーションに要した時間は含まれません。これらのアクティビティは、Test
ブロック内ではなく、TestMethodSetup
ブロック内で実行されます。ただし、測定時間には検証の実行に要した時間が含まれます。ベスト プラクティスは、より正確なパフォーマンス範囲を測定することです。
現在のフォルダー内に fprintfTest.m
という名前のファイルでパフォーマンス テストを作成します。このテストは、回帰テストと似ていますが、次の変更が加えられています。
テストは、
matlab.unittest.TestCase
ではなくmatlab.perftest.TestCase
から継承します。テストは、関数
fprintf
の呼び出しを囲むようにstartMeasuring
メソッドとstopMeasuring
メソッドを呼び出して範囲を作成します。
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.95
内で相対許容誤差 0.05
が達成されなかった旨の警告が表示される場合があります。
results = runperf("fprintfTest")
Running fprintfTest .......... .......... ... Done fprintfTest __________ results = 1×2 TimeResult array with properties: Name Valid Samples TestActivity Totals: 2 Valid, 0 Invalid. 3.6789 seconds testing time.
変数 results
は 1 行 2 列の TimeResult
配列です。配列の各要素は、テスト ファイルに定義されているテストの 1 つに対応しています。
テスト結果の表示
最初のテストの測定結果を表示します。結果は異なる場合があります。
results(1)
ans = TimeResult with properties: Name: 'fprintfTest/testPrintingToFile' Valid: 1 Samples: [4×7 table] TestActivity: [9×12 table] Totals: 1 Valid, 0 Invalid. 2.7009 seconds testing time.
TestActivity
プロパティのサイズで示されているとおり、パフォーマンス テスト フレームワークは 9 個の測定値を収集しました。この数には、コードをウォームアップするための 5 個の測定値が含まれています。Samples
プロパティでは、ウォームアップ測定値は除外されます。
最初のテストのサンプル測定値を表示します。
results(1).Samples
ans = 4×7 table Name MeasuredTime Timestamp Host Platform Version RunIdentifier ______________________________ ____________ ____________________ ___________ ________ __________________________________ ____________________________________ fprintfTest/testPrintingToFile 0.04193 14-Oct-2022 14:25:02 MY-HOSTNAME win64 9.14.0.2081372 (R2023a) Prerelease b8029663-5fbd-44e8-a5a6-06564ab18df6 fprintfTest/testPrintingToFile 0.04148 14-Oct-2022 14:25:02 MY-HOSTNAME win64 9.14.0.2081372 (R2023a) Prerelease b8029663-5fbd-44e8-a5a6-06564ab18df6 fprintfTest/testPrintingToFile 0.041849 14-Oct-2022 14:25:03 MY-HOSTNAME win64 9.14.0.2081372 (R2023a) Prerelease b8029663-5fbd-44e8-a5a6-06564ab18df6 fprintfTest/testPrintingToFile 0.041969 14-Oct-2022 14:25:03 MY-HOSTNAME win64 9.14.0.2081372 (R2023a) Prerelease b8029663-5fbd-44e8-a5a6-06564ab18df6
単一のテスト要素の統計の計算
最初のテストの平均測定時間を表示します。ウォームアップ実行で収集されたデータを除外するには、Samples
プロパティの値を使用します。
sampleTimes = results(1).Samples.MeasuredTime; meanTest = mean(sampleTimes)
meanTest = 0.0418
すべてのテスト要素の統計の計算
fprintf
の各種呼び出しを比較するために、results
から要約統計量の table を作成します。この例では、どちらのテスト メソッドも、同じ量のデータをファイルに書き込みます。そのため、一部の統計値の差は、出力引数を指定した関数 fprintf
の呼び出しに起因しています。
T = sampleSummary(results)
T = 2×7 table Name SampleSize Mean StandardDeviation Min Median Max ______________________________ __________ ________ _________________ ________ _______ ________ fprintfTest/testPrintingToFile 4 0.041807 0.00022367 0.04148 0.04189 0.041969 fprintfTest/testBytesToFile 9 0.044071 0.003268 0.041672 0.04223 0.049611
統計目標値の変更とテストの再実行
時間実験を作成および実行することで、関数 runperf
によって定義された統計目標値を変更します。信頼度 98%
以内、相対許容誤差 2%
でサンプル平均に達する測定での時間実験を作成します。4
個のウォームアップ測定値と、最大 16
個のサンプル測定値を収集します。
テスト スイートを作成します。
suite = testsuite("fprintfTest");
指定した要件で時間実験を構築して、テストを実行します。この例では、パフォーマンス テスト フレームワークは、指定された最大数のサンプルで、より厳密な統計目標値を満たすことができません。結果は異なる場合があります。
import matlab.perftest.TimeExperiment experiment = TimeExperiment.limitingSamplingError("NumWarmups",4, ... "MaxSamples",16,"RelativeMarginOfError",0.02,"ConfidenceLevel",0.98); resultsTE = run(experiment,suite);
Running fprintfTest
.......... .......... ........Warning: Target Relative Margin of Error not met after running the MaxSamples for fprintfTest/testBytesToFile.
Done fprintfTest
__________
サンプルの最大数を 32
に増やし、時間実験を再実行します。
experiment = TimeExperiment.limitingSamplingError("NumWarmups",4, ... "MaxSamples",32,"RelativeMarginOfError",0.02,"ConfidenceLevel",0.98); resultsTE = run(experiment,suite);
Running fprintfTest .......... .......... .......... . Done fprintfTest __________
テスト要素の要約統計量を計算します。
T1 = sampleSummary(resultsTE)
T1 = 2×7 table Name SampleSize Mean StandardDeviation Min Median Max ______________________________ __________ ________ _________________ ________ ________ ________ fprintfTest/testPrintingToFile 4 0.041632 4.2448e-05 0.041578 0.041638 0.041674 fprintfTest/testBytesToFile 19 0.042147 0.0016461 0.041428 0.041705 0.048784
初期コストの測定
新しい MATLAB® セッションを開始します。新しいセッションでは、MATLAB がテストに含まれるコードを確実に実行していません。
ウォームアップ測定数が 0 でサンプル測定数が 1 の固定回数時間実験を作成して実行することで、コードの初期コストを測定します。
テスト スイートを作成します。関数の初期コストを測定するため、単一のテストを実行します。複数のテストを実行するには、結果を保存して、テストのたびに新しい MATLAB セッションを開始します。
suite = testsuite("fprintfTest/testPrintingToFile");
時間実験を作成および実行します。
import matlab.perftest.TimeExperiment
experiment = TimeExperiment.withFixedSampleSize(1);
results = run(experiment,suite);
Running fprintfTest . Done fprintfTest __________
結果を表示します。table 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.044004 sample 14-Oct-2022 14:32:51 MY-HOSTNAME win64 9.14.0.2078117 (R2023a) Prerelease 1×1 matlab.unittest.TestResult be5b0bfd-9b87-4498-9ef3-675c6889a85c
参考
runperf
| testsuite
| matlab.perftest.TimeExperiment
| matlab.perftest.TestCase
| matlab.perftest.TimeResult