@@ -65,7 +65,7 @@ namespace SeqCli.Cli.Commands.Bench;
6565class BenchCommand : Command
6666{
6767 readonly SeqConnectionFactory _connectionFactory ;
68- int _runs = 3 ;
68+ int _runs = 10 ;
6969 readonly ConnectionFeature _connection ;
7070 readonly DateRangeFeature _range ;
7171 string _cases = "" ;
@@ -76,10 +76,7 @@ class BenchCommand : Command
7676 public BenchCommand ( SeqConnectionFactory connectionFactory )
7777 {
7878 _connectionFactory = connectionFactory ;
79- Options . Add ( "r|runs=" , "The number of runs to execute" , r =>
80- {
81- int . TryParse ( r , out _runs ) ;
82- } ) ;
79+ Options . Add ( "r|runs=" , "The number of runs to execute; the default is 10" , r => _runs = int . Parse ( r ) ) ;
8380
8481 Options . Add (
8582 "c|cases=" ,
@@ -108,56 +105,63 @@ protected override async Task<int> Run()
108105 try
109106 {
110107 var connection = _connectionFactory . Connect ( _connection ) ;
111- using var reportingLogger = BuildReportingLogger ( ) ;
108+ var seqVersion = ( await connection . Client . GetRootAsync ( ) ) . Version ;
109+
112110 var cases = ReadCases ( _cases ) ;
113- var runId = Guid . NewGuid ( ) . ToString ( "N" ) . Substring ( 0 , 4 ) ;
111+ var runId = Guid . NewGuid ( ) . ToString ( "N" ) [ ..16 ] ;
112+
113+ await using var reportingLogger = BuildReportingLogger ( ) ;
114114
115- if ( _range . Start == null || _range . End == null )
115+ using ( ! string . IsNullOrWhiteSpace ( _description )
116+ ? LogContext . PushProperty ( "Description" , _description )
117+ : null )
116118 {
117- Log . Error ( "Both the `start` and `end` arguments are required" ) ;
118- return 1 ;
119+ reportingLogger . Information (
120+ "Bench run {RunId} against {ServerUrl} ({SeqVersion}); {CaseCount} cases, {Runs} runs, from {Start} to {End}" ,
121+ runId , connection . Client . ServerUrl , seqVersion , cases . Cases . Count , _runs , _range . Start , _range . End ) ;
119122 }
120123
121- foreach ( var c in cases . Cases )
124+ using ( LogContext . PushProperty ( "RunId" , runId ) )
125+ using ( LogContext . PushProperty ( "Start" , _range . Start ) )
126+ using ( LogContext . PushProperty ( "End" , _range . End ) )
122127 {
123- var timings = new BenchCaseTimings ( ) ;
124- object ? lastResult = null ;
125-
126- foreach ( var i in Enumerable . Range ( 1 , _runs ) )
128+ foreach ( var c in cases . Cases )
127129 {
128- var response = await connection . Data . QueryAsync (
129- c . Query ,
130- _range . Start ,
131- _range . End ,
132- SignalExpressionPart . Signal ( c . SignalExpression )
133- ) ;
130+ var timings = new BenchCaseTimings ( ) ;
131+ object ? lastResult = null ;
134132
135- timings . PushElapsed ( response . Statistics . ElapsedMilliseconds ) ;
136-
137- if ( response . Rows != null )
133+ foreach ( var i in Enumerable . Range ( 1 , _runs ) )
138134 {
139- var isScalarResult = response . Rows . Length == 1 && response . Rows [ 0 ] . Length == 1 ;
140- if ( isScalarResult && i == _runs )
135+ var response = await connection . Data . QueryAsync (
136+ c . Query ,
137+ _range . Start ,
138+ _range . End ,
139+ c . SignalExpression != null ? SignalExpressionPart . Signal ( c . SignalExpression ) : null
140+ ) ;
141+
142+ timings . PushElapsed ( response . Statistics . ElapsedMilliseconds ) ;
143+
144+ if ( response . Rows != null )
141145 {
142- lastResult = response . Rows [ 0 ] [ 0 ] ;
146+ var isScalarResult = response . Rows . Length == 1 && response . Rows [ 0 ] . Length == 1 ;
147+ if ( isScalarResult && i == _runs )
148+ {
149+ lastResult = response . Rows [ 0 ] [ 0 ] ;
150+ }
143151 }
144152 }
145- }
146-
147- using ( lastResult != null ? LogContext . PushProperty ( "LastResult" , lastResult ) : null )
148- using ( LogContext . PushProperty ( "MinElapsed" , timings . MinElapsed ) )
149- using ( LogContext . PushProperty ( "MaxElapsed" , timings . MaxElapsed ) )
150- using ( LogContext . PushProperty ( "Runs" , _runs ) )
151- using ( ! string . IsNullOrWhiteSpace ( c . SignalExpression ) ? LogContext . PushProperty ( "SignalExpression" , c . SignalExpression ) : null )
152- using ( LogContext . PushProperty ( "Start" , _range . Start ) )
153- using ( LogContext . PushProperty ( "StandardDeviationElapsed" , timings . StandardDeviationElapsed ) )
154- using ( LogContext . PushProperty ( "End" , _range . End ) )
155- using ( LogContext . PushProperty ( "Query" , c . Query ) )
156- using ( ! string . IsNullOrWhiteSpace ( _description ) ? LogContext . PushProperty ( "Description" , _description ) : null )
157- {
158- reportingLogger . Information (
159- "Bench run {Cases}/{RunId} against {Server} for query {Id}: mean {MeanElapsed:N0} ms with relative dispersion {RelativeStandardDeviationElapsed:N2}" ,
160- cases . CasesHash , runId , _connection . Url , c . Id , timings . MeanElapsed , timings . RelativeStandardDeviationElapsed ) ;
153+
154+ using ( lastResult != null ? LogContext . PushProperty ( "LastResult" , lastResult ) : null )
155+ using ( ! string . IsNullOrWhiteSpace ( c . SignalExpression )
156+ ? LogContext . PushProperty ( "SignalExpression" , c . SignalExpression )
157+ : null )
158+ using ( LogContext . PushProperty ( "StandardDeviationElapsed" , timings . StandardDeviationElapsed ) )
159+ using ( LogContext . PushProperty ( "Query" , c . Query ) )
160+ {
161+ reportingLogger . Information (
162+ "Case {Id,-40} mean {MeanElapsed,5:N0} ms (min {MinElapsed,5:N0} ms, max {MaxElapsed,5:N0} ms, RSD {RelativeStandardDeviationElapsed,4:N2})" ,
163+ c . Id , timings . MeanElapsed , timings . MinElapsed , timings . MaxElapsed , timings . RelativeStandardDeviationElapsed ) ;
164+ }
161165 }
162166 }
163167
@@ -197,28 +201,20 @@ static BenchCasesCollection ReadCases(string filename)
197201 var casesString = File . ReadAllText ( string . IsNullOrWhiteSpace ( filename )
198202 ? defaultCasesPath
199203 : filename ) ;
204+
200205 var casesFile = JsonConvert . DeserializeObject < BenchCasesCollection > ( casesString )
201206 ?? new BenchCasesCollection ( ) ;
202207
203- casesFile . CasesHash = HashString ( casesString ) ;
204-
205208 if ( casesFile . Cases . Select ( c => c . Id ) . Distinct ( ) . Count ( ) != casesFile . Cases . Count )
206209 {
207- throw new Exception ( $ "Cases file { filename } contains a duplicate id") ;
210+ throw new ArgumentException ( $ "Cases file ` { filename } ` contains a duplicate id. ") ;
208211 }
209212
210213 if ( ! casesFile . Cases . Any ( ) )
211214 {
212- throw new Exception ( $ "Cases file { filename } contains no cases") ;
215+ throw new ArgumentException ( $ "Cases file ` { filename } ` contains no cases. ") ;
213216 }
214217
215218 return casesFile ;
216219 }
217-
218- static string HashString ( string input )
219- {
220- using var md5 = MD5 . Create ( ) ;
221- var bytes = Encoding . ASCII . GetBytes ( input ) ;
222- return Convert . ToHexString ( md5 . ComputeHash ( bytes ) ) ;
223- }
224220}
0 commit comments