1
- #I @" ../../packages/build/FAKE/tools"
1
+ #r " ../../packages/build/NEST/lib/net45/Nest.dll"
2
+ #r " ../../packages/build/Elasticsearch.Net/lib/net45/Elasticsearch.Net.dll"
3
+ #r " ../../packages/build/Newtonsoft.Json/lib/net45/Newtonsoft.Json.dll"
4
+ #r " ../../packages/build/FSharp.Data/lib/net40/FSharp.Data.dll"
5
+ #I @" ../../packages/build/FAKE/tools"
2
6
#r @" FakeLib.dll"
7
+ #nowarn " 0044" //TODO sort out FAKE 5
8
+
3
9
open Fake
4
10
5
11
#load @" Paths.fsx"
@@ -10,20 +16,113 @@ open System.Linq
10
16
open System.Diagnostics
11
17
open Paths
12
18
19
+ open FSharp.Data
20
+
21
+ open Nest
22
+ open Elasticsearch.Net
23
+ open Newtonsoft.Json
24
+ open Git.Branches
25
+
13
26
module Benchmarker =
14
- let private testsProjectDirectory = Path.GetFullPath( Paths.Source( " Tests" ))
15
- let private benchmarkOutput = Path.GetFullPath( Paths.Output( " benchmarks" )) |> directoryInfo
16
27
17
- let private copyToOutput file = CopyFile benchmarkOutput.FullName file
28
+ type ProcessorName ( isValueCreated : bool , value : string ) =
29
+ member val IsValueCreated = isValueCreated with get, set
30
+ member val Value = value with get, set
31
+
32
+ type ChronometerFrequency ( hertz : int ) =
33
+ member val Hertz = hertz with get, set
34
+
35
+ type HostEnvironmentInfo ( benchmarkDotNetCaption : string , benchmarkDotNetVersion : string , osVersion : string , processorName : ProcessorName ,
36
+ processorCount: int, runtimeVersion: string, architecture: string, hasAttachedDebugger: bool, hasRyuJit: bool,
37
+ configuration: string, jitModules: string, dotnetCliVersion: string, chronometerFrequency: ChronometerFrequency,
38
+ hardwareTimerKind: string) =
39
+ member val BenchmarkDotNetCaption = benchmarkDotNetCaption with get, set
40
+ member val BenchmarkDotNetVersion = benchmarkDotNetVersion with get, set
41
+ member val OsVersion = osVersion with get, set
42
+ member val ProcessorName = processorName with get, set
43
+ member val ProcessorCount = processorCount with get, set
44
+ member val RuntimeVersion = runtimeVersion with get, set
45
+ member val Architecture = architecture with get, set
46
+ member val HasAttachedDebugger = hasAttachedDebugger with get, set
47
+ member val HasRyuJit = hasRyuJit with get, set
48
+ member val Configuration = configuration with get, set
49
+ member val JitModules = jitModules with get, set
50
+ member val DotNetCliVersion = dotnetCliVersion with get, set
51
+ member val ChronometerFrequency = chronometerFrequency with get, set
52
+ member val HardwareTimerKind = hardwareTimerKind with get, set
53
+
54
+ type ConfidenceInterval ( mean : double , error : double , level : int , margin : double , lower : double , upper : double ) =
55
+ member val Mean = mean with get, set
56
+ member val Error = error with get, set
57
+ member val Level = level with get, set
58
+ member val Margin = margin with get, set
59
+ member val Lower = lower with get, set
60
+ member val Upper = upper with get, set
61
+
62
+ type Percentiles ( p0 : double , p25 : double , p50 : double , p67 : double , p80 : double , p85 : double , p90 : double , p95 : double , p100 : double ) =
63
+ member val P0 = p0 with get, set
64
+ member val P25 = p25 with get, set
65
+ member val P50 = p50 with get, set
66
+ member val P67 = p67 with get, set
67
+ member val P80 = p80 with get, set
68
+ member val P85 = p85 with get, set
69
+ member val P90 = p90 with get, set
70
+ member val P95 = p95 with get, set
71
+ member val P100 = p100 with get, set
72
+
73
+ type Statistics ( n : int , min : double , lowerFence : double , q1 : double , median : double , mean : double , q3 : double , upperFence : double , max : double ,
74
+ interquartileRange: double, outliers: double list, standardError: double, variance: double, standardDeviation: double,
75
+ skewness: double, kurtosis: double, confidenceInterval: ConfidenceInterval, percentiles: Percentiles) =
76
+ member val N = n with get, set
77
+ member val Min = min with get, set
78
+ member val LowerFence = lowerFence with get, set
79
+ member val Q1 = q1 with get, set
80
+ member val Median = median with get, set
81
+ member val Mean = mean with get, set
82
+ member val Q3 = q3 with get, set
83
+ member val UpperFence = upperFence with get, set
84
+ member val Max = max with get, set
85
+ member val InterquartileRange = interquartileRange with get, set
86
+ member val Outliers = outliers with get, set
87
+ member val StandardError = standardError with get, set
88
+ member val Variance = variance with get, set
89
+ member val StandardDeviation = standardDeviation with get, set
90
+ member val Skewness = skewness with get, set
91
+ member val Kurtosis = kurtosis with get, set
92
+ member val ConfidenceInterval = confidenceInterval with get, set
93
+ member val Percentiles = percentiles with get, set
94
+
95
+ type Benchmark ( displayInfo : string , namespyce : string , tipe : string , method : string , methodTitle : string , parameters : string , statistics : Statistics ) =
96
+ member val DisplayInfo = displayInfo with get, set
97
+ member val Namespace = namespyce with get, set
98
+ member val Type = tipe with get, set
99
+ member val Method = method with get, set
100
+ member val MethodTitle = methodTitle with get, set
101
+ member val Parameters = parameters with get, set
102
+ member val Statistics = statistics with get, set
103
+
104
+ type Report ( title : string , date : DateTime , commit : string , host : HostEnvironmentInfo , benchmarks : Benchmark list ) =
105
+ member val Title = title with get, set
106
+ member val Date = date with get, set
107
+ member val Commit = commit with get, set
108
+ member val HostEnvironmentInfo = host with get, set
109
+ member val Benchmarks = benchmarks with get, set
110
+
111
+ let private testsProjectDirectory = Path.GetFullPath( Paths.Source( " Tests" ))
112
+ let private benchmarkOutput = Path.GetFullPath( Paths.Output( " benchmarks" )) |> directoryInfo
113
+ let private copyToOutput file = CopyFile benchmarkOutput.FullName file
114
+
115
+ let Run () =
18
116
19
- let Run () =
20
117
ensureDirExists benchmarkOutput
118
+
21
119
let projectJson = testsProjectDirectory @@ " project.json"
120
+
22
121
// running benchmarks can timeout so clean up any generated benchmark files
23
122
try
24
123
DotNetCli.RunCommand( fun p ->
25
124
{ p with
26
- WorkingDir = testsProjectDirectory
125
+ WorkingDir = testsProjectDirectory
27
126
}) " run -f net46 -c Release Benchmark"
28
127
finally
29
128
let benchmarkOutputFiles =
@@ -33,3 +132,77 @@ module Benchmarker =
33
132
34
133
for file in benchmarkOutputFiles do copyToOutput file
35
134
DeleteFiles benchmarkOutputFiles
135
+
136
+ let IndexResult ( client : ElasticClient , file : string , date : DateTime , commit : string , indexName , typeName ) =
137
+
138
+ let document = JsonConvert.DeserializeObject< Report>( File.ReadAllText( file))
139
+ document.Date <- date
140
+ document.Commit <- commit
141
+
142
+ let indexRequest = new IndexRequest< Report>( indexName, typeName)
143
+ indexRequest.Document <- document
144
+ indexRequest.Pipeline <- " benchmark-pipeline"
145
+
146
+ let indexResponse = client.Index( indexRequest)
147
+
148
+ if indexResponse.IsValid = false then
149
+ raise ( Exception( " Unable to index report into Elasticsearch: " + indexResponse.ServerError.Error.ToString()))
150
+
151
+ let IndexResults url =
152
+ if ( String.IsNullOrEmpty url = false ) then
153
+ trace " Indexing benchmark results into Elasticsearch"
154
+
155
+ let date = DateTime.UtcNow
156
+ let commit = getSHA1 " ." " HEAD"
157
+
158
+ let benchmarkJsonFiles =
159
+ Directory.EnumerateFiles( benchmarkOutput.FullName, " *-brief.json" , SearchOption.AllDirectories)
160
+ |> Seq.toList
161
+
162
+ let uri = new Uri( url)
163
+ let client = new ElasticClient( uri)
164
+
165
+ let indexName = IndexName.op_ Implicit( " reports" )
166
+ let typeName = TypeName.op_ Implicit( " report" )
167
+ let indexExists = client.IndexExists( Indices.op_ Implicit( indexName)) .Exists
168
+
169
+ if indexExists = false then
170
+ let createIndex = client.CreateIndex( indexName, fun c ->
171
+ c.Mappings( fun m ->
172
+ m.Map< Report>( fun mm ->
173
+ mm.AutoMap()
174
+ .Properties( fun p ->
175
+ p.Nested< Benchmark>( fun n ->
176
+ n.AutoMap() .Name( PropertyName.op_ Implicit( " benchmarks" )) :> INestedProperty
177
+ ) :> IPromise< IProperties>
178
+ ) :> ITypeMapping
179
+ ) :> IPromise< IMappings>
180
+ ) :> ICreateIndexRequest
181
+ )
182
+
183
+ if createIndex.IsValid = false then
184
+ raise ( Exception( " Unable to create index into Elasticsearch" ))
185
+
186
+ //let pipelineExists = client.GetPipeline(new GetPipelineRequest(Id.op_Implicit("benchmark-pipeline")))
187
+
188
+ //if pipelineExists.IsValid = false then
189
+ let forEachProcessor = new ForeachProcessor()
190
+ let processor = new GrokProcessor();
191
+ processor.Field <- new Field( " _ingest._value.displayInfo" )
192
+ processor.Patterns <- [ " %{WORD:_ingest._value.class}.%{WORD:_ingest._value.method}: Job-%{WORD:_ingest._value.jobName}\\ (Jit=%{WORD:_ingest._value.jit}, Runtime=%{WORD:_ingest._value.clr}, LaunchCount=%{NUMBER:_ingest._value.launchCount}, RunStrategy=%{WORD:_ingest._value.runStrategy}, TargetCount=%{NUMBER:_ingest._value.targetCount}, UnrollFactor=%{NUMBER:_ingest._value.unrollFactor}, WarmupCount=%{NUMBER:_ingest._value.warmupCount}\\ )" ]
193
+
194
+ forEachProcessor.Field <- new Field( " benchmarks" )
195
+ forEachProcessor.Processor <- processor
196
+
197
+ let request = new PutPipelineRequest( Id.op_ Implicit( " benchmark-pipeline" ))
198
+ request.Description <- " Grok benchmark settings"
199
+ request.Processors <- [ forEachProcessor]
200
+
201
+ let createPipeline = client.PutPipeline( request)
202
+
203
+ if createPipeline.IsValid = false then
204
+ raise ( Exception( " Unable to create pipeline" ))
205
+
206
+ for file in benchmarkJsonFiles do IndexResult ( client, file, date, commit, indexName, typeName)
207
+
208
+ trace " Indexed benchmark results into Elasticsearch"
0 commit comments