Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

クラスを使用したパフォーマンスのテスト

この例では、関数 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.
   4.1417 seconds testing time.

変数 results12 列の TimeResult 配列です。配列の各要素は、テスト ファイルに定義されているテストの 1 つに対応しています。

テスト結果の表示

最初のテストの測定結果を表示します。結果は異なる場合があります。

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 テストには、2 つの異なるメソッドが含まれます。各メソッド (テスト要素) の時間を比較します。

パフォーマンス テスト フレームワークは各テスト要素の Samples テーブルを返すため、これらのテーブルをすべて 1 つのテーブルに連結します。次に、テスト要素 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 によって定義された統計目標値を変更します。信頼度 97% 以内、相対許容誤差 3% でサンプル平均に達する測定での時間実験を作成します。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 がテストに含まれるコードを確実に実行していません。

ウォームアップ測定数が 0 でサンプル測定数が 1 の固定回数時間実験を作成して実行することで、コードの初期コストを測定します。

明示的なテスト スイートを作成します。関数の初期コストを測定するため、単一のテストを実行します。複数のテストを実行するには、結果を保存して、テストのたびに新しい 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

パフォーマンス テスト フレームワークは、テストごとに 1 つのサンプルを収集します。

参考

| | | | |