@@ -102,6 +102,8 @@ function runplotlytests(varargin)
102102 % including each parameterized case
103103 hasSetup = ismember(' setUp' , classMeths );
104104 hasTearDown = ismember(' tearDown' , classMeths );
105+ isPerfClass = isa(tc , ' PlotlyPerfTestCase' );
106+ perfRows = {};
105107 nTests = 0 ;
106108 verdicts = struct(' Name' , {}, ' Passed' , {}, ' VerificationFailures' , {}, ...
107109 ' Diagnostics' , {}, ' ErrorTrace' , {}, ' Duration' , {}, ' Errored' , {});
@@ -230,6 +232,16 @@ function runplotlytests(varargin)
230232 else
231233 fprintf(' .' );
232234 end
235+
236+ if isPerfClass
237+ st = tc .sampleStats();
238+ if st .NumSamples > 0
239+ fprintf(' \n %s : %s mean, %s MoE, n=%d (%d warmups)\n ' , ...
240+ caseName , fmtTime(st .Mean), fmtMoE(st .RelMoE), ...
241+ st .NumSamples, st .NumWarmups);
242+ perfRows{end + 1 } = struct(' Name' , caseName , ' Stats' , st ); % #ok<AGROW>
243+ end
244+ end
233245 end
234246 end
235247
@@ -242,6 +254,25 @@ function runplotlytests(varargin)
242254 ' ErrorTrace' , ' ' , ' Duration' , 0 , ' Errored' , true );
243255 end
244256
257+ if ~isempty(perfRows )
258+ maxName = 0 ;
259+ for r = 1 : numel(perfRows )
260+ maxName = max(maxName , length(perfRows{r }.Name));
261+ end
262+ fprintf(' \n Sample summary:\n ' );
263+ hdr = sprintf(' %-*s %4s %10s %10s %10s %10s %7s\n ' , ...
264+ maxName , ' Name' , ' n' , ' Mean' , ' Std' , ' Min' , ' Max' , ' MoE' );
265+ fprintf(' %s ' , hdr );
266+ fprintf(' %s\n ' , repmat(' -' , 1 , numel(hdr ) - 1 ));
267+ for r = 1 : numel(perfRows )
268+ st = perfRows{r }.Stats;
269+ fprintf(' %-*s %4d %10s %10s %10s %10s %7s\n ' , ...
270+ maxName , perfRows{r }.Name, st .NumSamples, ...
271+ fmtSec(st .Mean), fmtSec(st .Std), fmtSec(st .Min), ...
272+ fmtSec(st .Max), fmtMoE(st .RelMoE));
273+ end
274+ end
275+
245276 fprintf(' \n Done %s\n ' , className );
246277 fprintf(' __________\n\n ' );
247278
@@ -542,6 +573,29 @@ function runplotlytests(varargin)
542573 end
543574end
544575
576+ function s = fmtTime(t )
577+ % auto-scaled time for the inline per-case line
578+ if t < 1
579+ s = sprintf(' %.2f ms' , t * 1000 );
580+ else
581+ s = sprintf(' %.3f s' , t );
582+ end
583+ end
584+
585+ function s = fmtSec(t )
586+ % fixed seconds for the sample summary columns
587+ s = sprintf(' %.6g ' , t );
588+ end
589+
590+ function s = fmtMoE(r )
591+ % relative margin of error as a percentage
592+ if isempty(r ) || ~isfinite(r )
593+ s = ' n/a' ;
594+ else
595+ s = sprintf(' %.1f%% ' , r * 100 );
596+ end
597+ end
598+
545599function trace = errorTrace(e )
546600 trace = sprintf(' ''%s''\n%s ' , e .identifier, e .message);
547601 for si = 1 : numel(e .stack)
0 commit comments