diff --git a/.gitignore b/.gitignore
index 4a2cef28006..22d936056cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,6 +41,7 @@ packages/*
paket.exe
paket-files/*.cached
+BenchmarkDotNet.Artifacts
build/*
!build/tools
!build/keys
diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets
index 7c6107011de..d93abfef97a 100644
--- a/.paket/Paket.Restore.targets
+++ b/.paket/Paket.Restore.targets
@@ -151,15 +151,17 @@
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length)
$([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0])
$([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1])
$([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4])
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5])
%(PaketReferencesFileLinesInfo.PackageVersion)
All
- runtime
+ runtime
+ runtime
true
@@ -192,19 +194,27 @@
false
+ $(MSBuildVersion)
+ 15.8.0
<_NuspecFilesNewLocation Include="$(BaseIntermediateOutputPath)$(Configuration)\*.nuspec"/>
+
+
$(MSBuildProjectDirectory)/$(MSBuildProjectFile)
true
- false
- true
+ false
+ true
+ false
+ true
+ false
+ true
$(BaseIntermediateOutputPath)$(Configuration)
$(BaseIntermediateOutputPath)
@@ -219,9 +229,52 @@
-
-
+
+
-
-
+
\ No newline at end of file
diff --git a/build/scripts/Benchmarking.fsx b/build/scripts/Benchmarking.fsx
index 68aee6475a8..9a5a499b302 100644
--- a/build/scripts/Benchmarking.fsx
+++ b/build/scripts/Benchmarking.fsx
@@ -1,257 +1,32 @@
-#r "../../packages/build/NEST/lib/net46/Nest.dll"
-#r "../../packages/build/Elasticsearch.Net/lib/net46/Elasticsearch.Net.dll"
-#r "../../packages/build/Newtonsoft.Json/lib/net45/Newtonsoft.Json.dll"
-#r "../../packages/build/FSharp.Data/lib/net45/FSharp.Data.dll"
-#I @"../../packages/build/FAKE/tools"
+#I @"../../packages/build/FAKE/tools"
#r @"FakeLib.dll"
#nowarn "0044" //TODO sort out FAKE 5
-open Fake
-
+#load @"Commandline.fsx"
#load @"Paths.fsx"
-open System
+open Fake
open System.IO
-open System.Linq
-open System.Diagnostics
open Paths
-
-open FSharp.Data
-
-open Nest
-open Elasticsearch.Net
-open Newtonsoft.Json
-open Git.Branches
-open Git.Information
+open Commandline
module Benchmarker =
- let pipelineName = "benchmark-pipeline"
- let indexName = IndexName.op_Implicit("benchmark-reports")
- let typeName = TypeName.op_Implicit("benchmarkreport")
-
- type Memory(gen0Collections:int, gen1Collections: int, gen2Collections: int, totalOperations:int64, bytesAllocatedPerOperation:int64) =
- member val Gen0Collections=gen0Collections with get, set
- member val Gen1Collections=gen1Collections with get, set
- member val Gen2Collections=gen2Collections with get, set
- member val TotalOperations=totalOperations with get, set
- member val BytesAllocatedPerOperation=bytesAllocatedPerOperation with get, set
-
- type ChronometerFrequency(hertz:double) =
- member val Hertz=hertz with get, set
-
- type HostEnvironmentInfo(benchmarkDotNetCaption:string, benchmarkDotNetVersion:string, osVersion: string, processorName:string,
- processorCount:int, runtimeVersion:string, architecture:string, hasAttachedDebugger:bool, hasRyuJit:bool,
- configuration:string, jitModules:string, dotnetCliVersion:string, chronometerFrequency:ChronometerFrequency,
- hardwareTimerKind:string) =
- member val BenchmarkDotNetCaption=benchmarkDotNetCaption with get, set
- member val BenchmarkDotNetVersion=benchmarkDotNetVersion with get, set
- member val OsVersion=osVersion with get, set
- member val ProcessorName=processorName with get, set
- member val ProcessorCount=processorCount with get, set
- member val RuntimeVersion=runtimeVersion with get, set
- member val Architecture=architecture with get, set
- member val HasAttachedDebugger=hasAttachedDebugger with get, set
- member val HasRyuJit=hasRyuJit with get, set
- member val Configuration=configuration with get, set
- member val JitModules=jitModules with get, set
- member val DotNetCliVersion=dotnetCliVersion with get, set
- member val ChronometerFrequency=chronometerFrequency with get, set
- member val HardwareTimerKind=hardwareTimerKind with get, set
-
- type ConfidenceInterval(n:int, mean: double, standardError:double, level:int, margin:double, lower:double, upper:double) =
- member val N=n with get, set
- member val Mean=mean with get, set
- member val StandardError=standardError with get, set
- member val Level=level with get, set
- member val Margin=margin with get, set
- member val Lower=lower with get, set
- member val Upper=upper with get, set
-
- type Percentiles (p0:double, p25:double, p50:double, p67:double, p80:double, p85:double, p90:double, p95:double, p100:double) =
- member val P0=p0 with get, set
- member val P25=p25 with get, set
- member val P50=p50 with get, set
- member val P67=p67 with get, set
- member val P80=p80 with get, set
- member val P85=p85 with get, set
- member val P90=p90 with get, set
- member val P95=p95 with get, set
- member val P100=p100 with get, set
-
- type Statistics(n:int, min:double, lowerFence:double, q1:double, median:double, mean:double, q3:double, upperFence:double, max:double,
- interquartileRange:double, outliers:double list, standardError:double, variance:double, standardDeviation:double,
- skewness:double, kurtosis:double, confidenceInterval:ConfidenceInterval, percentiles:Percentiles) =
- member val N=n with get, set
- member val Min=min with get, set
- member val LowerFence=lowerFence with get, set
- member val Q1=q1 with get, set
- member val Median=median with get, set
- member val Mean=mean with get, set
- member val Q3=q3 with get, set
- member val UpperFence=upperFence with get, set
- member val Max=max with get, set
- member val InterquartileRange=interquartileRange with get, set
- member val Outliers=outliers with get, set
- member val StandardError=standardError with get, set
- member val Variance=variance with get, set
- member val StandardDeviation=standardDeviation with get, set
- member val Skewness=skewness with get, set
- member val Kurtosis=kurtosis with get, set
- member val ConfidenceInterval=confidenceInterval with get, set
- member val Percentiles=percentiles with get, set
-
- type Benchmark(displayInfo:string, namespyce:string, tipe:string, method:string, methodTitle:string, parameters:string,
- statistics:Statistics, memory:Memory) =
- member val DisplayInfo=displayInfo with get, set
- member val Namespace=namespyce with get, set
- member val Type=tipe with get, set
- member val Method=method with get, set
- member val MethodTitle=methodTitle with get, set
- member val Parameters=parameters with get, set
- member val Statistics=statistics with get, set
- member val Memory=memory with get, set
-
- type BenchmarkReports(title: string, totalTime:TimeSpan, date:DateTime, commit:string, branchName:string, host:HostEnvironmentInfo, benchmarks:Benchmark list) =
- member val Title = title with get, set
- member val TotalTime = totalTime with get, set
- member val Date = date with get, set
- member val Commit = commit with get, set
- member val BranchName = branchName with get, set
- member val HostEnvironmentInfo = host with get, set
- member val Benchmarks = benchmarks with get, set
-
- type BenchmarkReport(title: string, totalTime:TimeSpan, date:DateTime, commit:string, branchName:string, host:HostEnvironmentInfo, benchmark:Benchmark) =
- member val Title = title with get, set
- member val TotalTime = totalTime with get, set
- member val Date = date with get, set
- member val Commit = commit with get, set
- member val BranchName = branchName with get, set
- member val HostEnvironmentInfo = host with get, set
- member val Benchmark = benchmark with get, set
-
let private testsProjectDirectory = Path.GetFullPath(Paths.TestsSource("Tests.Benchmarking"))
- let private benchmarkOutput = Path.GetFullPath(Paths.Output("benchmarks")) |> directoryInfo
- let private copyToOutput file = CopyFile benchmarkOutput.FullName file
-
- let Run(runInteractive:bool) =
-
- ensureDirExists benchmarkOutput
-
- try
- if runInteractive then
- DotNetCli.RunCommand(fun p ->
- { p with
- WorkingDir = testsProjectDirectory
- }) "run -f netcoreapp2.1 -c Release"
- else
- DotNetCli.RunCommand(fun p ->
- { p with
- WorkingDir = testsProjectDirectory
- }) "run -f netcoreapp2.1 -c Release non-interactive"
- finally
- // running benchmarks can timeout so clean up any generated benchmark files
- let benchmarkOutputFiles =
- let output = combinePaths testsProjectDirectory "BenchmarkDotNet.Artifacts"
- Directory.EnumerateFiles(output, "*.*", SearchOption.AllDirectories)
- |> Seq.toList
-
- for file in benchmarkOutputFiles do copyToOutput file
- DeleteFiles benchmarkOutputFiles
-
- let IndexResult (client:ElasticClient, file:string, date:DateTime, commit:string, branchName:string, indexName, typeName) =
-
- trace (sprintf "Indexing benchmark results (class) %s" file)
-
- let benchmarkReports = JsonConvert.DeserializeObject(File.ReadAllText(file))
- benchmarkReports.Date <- date
- benchmarkReports.Commit <- commit
- benchmarkReports.BranchName <- branchName
-
- for benchmarkReportSingle in benchmarkReports.Benchmarks do
-
- trace (sprintf "Indexing benchmark result (method) %s" benchmarkReportSingle.MethodTitle)
-
- let document = new BenchmarkReport(benchmarkReports.Title,
- benchmarkReports.TotalTime,
- benchmarkReports.Date,
- benchmarkReports.Commit,
- benchmarkReports.BranchName,
- benchmarkReports.HostEnvironmentInfo,
- benchmarkReportSingle)
-
- let indexRequest = new IndexRequest(indexName, typeName)
- indexRequest.Document <- document
- indexRequest.Pipeline <- pipelineName
-
- let indexResponse = client.Index(indexRequest)
-
- if indexResponse.IsValid = false then
- raise (Exception("Unable to index benchmark result (method): " + indexResponse.ServerError.Error.ToString()))
-
- let IndexResults (url, username, password) =
- if (String.IsNullOrEmpty url = false) then
- trace "Indexing benchmark reports"
-
- let date = DateTime.UtcNow
- let commit = getSHA1 "." "HEAD"
- let branchName = getBranchName "."
-
- let benchmarkJsonFiles =
- Directory.EnumerateFiles(benchmarkOutput.FullName, "*-custom.json", SearchOption.AllDirectories)
- |> Seq.toList
-
- let uri = new Uri(url)
- let connectionSettings = new ConnectionSettings(uri);
-
- if (String.IsNullOrEmpty username = false && String.IsNullOrEmpty password = false) then
- connectionSettings.BasicAuthentication(username, password) |> ignore
-
- let client = new ElasticClient(connectionSettings)
-
- let indexTemplateExists = client.IndexTemplateExists(Name.op_Implicit("benchmarks")).Exists
-
- if indexTemplateExists |> not then
-
- let typeMapping = new TypeMappingDescriptor()
- typeMapping.AutoMap() |> ignore
-
- let mappings = new Mappings()
- mappings.Add(typeName, typeMapping :> ITypeMapping)
-
- let indexSettings = new IndexSettings()
- indexSettings.NumberOfShards <- Nullable 1
-
- let putIndexTemplateRequest = new PutIndexTemplateRequest(Name.op_Implicit("benchmarks"))
- putIndexTemplateRequest.IndexPatterns <- ["benchmark-reports-*"]
- putIndexTemplateRequest.Mappings <- mappings
- putIndexTemplateRequest.Settings <- indexSettings
-
- let putIndexTemplateResponse = client.PutIndexTemplate(putIndexTemplateRequest)
-
- if putIndexTemplateResponse.IsValid = false then
- raise (Exception("Unable to create index template into Elasticsearch"))
-
- let grokProcessor = new GrokProcessor();
- grokProcessor.Field <- new Field("benchmark.displayInfo")
- grokProcessor.Patterns <- ["%{WORD:class}.%{DATA:method}: Job-%{WORD:jobName}\\(Jit=%{WORD:jit}, Runtime=%{WORD:clr}, LaunchCount=%{NUMBER:launchCount}, RunStrategy=%{WORD:runStrategy}, TargetCount=%{NUMBER:targetCount}, UnrollFactor=%{NUMBER:unrollFactor}, WarmupCount=%{NUMBER:warmupCount}\\)"]
-
- let dateIndexProcessor = new DateIndexNameProcessor();
- dateIndexProcessor.Field <- new Field("date")
- dateIndexProcessor.IndexNamePrefix <- "benchmark-reports-"
- dateIndexProcessor.DateRounding <- new Nullable(DateRounding.Month)
- dateIndexProcessor.DateFormats <- ["yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ"]
-
- let request = new PutPipelineRequest(Id.op_Implicit(pipelineName))
- request.Description <- "Benchmark settings pipeline"
- request.Processors <- [dateIndexProcessor; grokProcessor]
-
- let createPipeline = client.PutPipeline(request)
-
- if createPipeline.IsValid = false then
- raise (Exception("Unable to create pipeline"))
-
- for file in benchmarkJsonFiles
- do IndexResult (client, file, date, commit, branchName, indexName, typeName)
- trace "Indexed benchmark reports"
\ No newline at end of file
+ let Run() =
+ let runInteractive = not Commandline.nonInteractive
+ let url = getBuildParam "elasticsearch"
+ let username = getBuildParam "username"
+ let password = getBuildParam "password"
+ let hasUrl = not <| isNullOrEmpty url
+ let hasCredentials = not <| (isNullOrEmpty username && isNullOrEmpty password)
+ let runCommandPrefix = "run -f netcoreapp2.1 -c Release"
+ let runCommand =
+ match (runInteractive, hasUrl, hasCredentials) with
+ | (false, true, true) -> sprintf "%s -- --all \"%s\" \"%s\" \"%s\"" runCommandPrefix url username password
+ | (false, true, false) -> sprintf "%s -- --all \"%s\"" runCommandPrefix url
+ | (false, _, _) -> sprintf "%s -- --all" runCommandPrefix
+ | (true, _, _) -> runCommandPrefix
+
+ DotNetCli.RunCommand(fun p -> { p with WorkingDir = testsProjectDirectory }) runCommand
diff --git a/build/scripts/Commandline.fsx b/build/scripts/Commandline.fsx
index 43ba81bf304..512a6421a38 100644
--- a/build/scripts/Commandline.fsx
+++ b/build/scripts/Commandline.fsx
@@ -32,7 +32,7 @@ Targets:
* cluster [version]
- Start a cluster defined in Tests.Core or Tests from the command line and leaves it running
untill a key is pressed. Handy if you want to run the integration tests numerous times while developing
-* benchmark [url] [username] [password] [non-interactive]
+* benchmark [non-interactive] [url] [username] [password]
- Runs a benchmark from Tests.Benchmarking and indexes the results to [url] when provided.
If non-interactive runs all benchmarks without prompting
@@ -41,6 +41,7 @@ NOTE: both the `test` and `integrate` targets can be suffixed with `-all` to for
Execution hints can be provided anywhere on the command line
- skiptests : skip running tests as part of the target chain
- skipdocs : skip generating documentation
+- non-interactive : make targets that run in interactive mode by default to run unassisted.
- docs: : the branch name B to use when generating documentation
- seed: : provide a seed to run the tests with.
- random:<:B> : sets random K to bool B if if B is omitted will default to true
@@ -52,6 +53,7 @@ module Commandline =
let private args = getBuildParamOrDefault "cmdline" "build" |> split ' '
+ let nonInteractive = args |> List.exists (fun x -> x = "non-interactive")
let skipTests = args |> List.exists (fun x -> x = "skiptests")
let skipDocs = args |> List.exists (fun x -> x = "skipdocs") || isMono
let seed =
@@ -75,6 +77,7 @@ module Commandline =
fun x ->
x <> "skiptests" &&
x <> "skipdocs" &&
+ x <> "non-interactive" &&
not (x.StartsWith("seed:")) &&
not (x.StartsWith("random:")) &&
not (x.StartsWith("docs:"))
@@ -152,29 +155,13 @@ module Commandline =
| ["test"; testFilter] -> setBuildParam "testfilter" testFilter
- | ["benchmark"; IsUrl elasticsearch; username; password; "non-interactive"] ->
- setBuildParam "elasticsearch" elasticsearch
- setBuildParam "nonInteractive" "1"
- setBuildParam "username" username
- setBuildParam "password" password
-
- | ["benchmark"; IsUrl elasticsearch; "non-interactive"] ->
- setBuildParam "elasticsearch" elasticsearch
- setBuildParam "nonInteractive" "1"
-
- | ["benchmark"; "non-interactive"] ->
- setBuildParam "nonInteractive" "1"
-
| ["benchmark"; IsUrl elasticsearch; username; password] ->
setBuildParam "elasticsearch" elasticsearch
- setBuildParam "nonInteractive" "0"
setBuildParam "username" username
setBuildParam "password" password
-
| ["benchmark"; IsUrl elasticsearch] ->
setBuildParam "elasticsearch" elasticsearch
- setBuildParam "nonInteractive" "0"
-
+
| ["profile"; IsUrl elasticsearch] ->
setBuildParam "elasticsearch" elasticsearch
diff --git a/build/scripts/Paths.fsx b/build/scripts/Paths.fsx
index 6233e4bd345..6666bd24e47 100644
--- a/build/scripts/Paths.fsx
+++ b/build/scripts/Paths.fsx
@@ -4,11 +4,6 @@
#load @"Projects.fsx"
-open System
-open System.IO
-open System.Diagnostics
-open System.Net
-
open Fake
open Projects
diff --git a/build/scripts/Targets.fsx b/build/scripts/Targets.fsx
index d897172070c..ac0ee5246a4 100644
--- a/build/scripts/Targets.fsx
+++ b/build/scripts/Targets.fsx
@@ -59,13 +59,7 @@ Target "Profile" <| fun _ ->
Target "Integrate" Tests.RunIntegrationTests
-Target "Benchmark" <| fun _ ->
- let runInteractive = ((getBuildParam "nonInteractive") <> "1")
- Benchmarker.Run(runInteractive)
- let url = getBuildParam "elasticsearch"
- let username = getBuildParam "username"
- let password = getBuildParam "password"
- Benchmarker.IndexResults (url, username, password)
+Target "Benchmark" Benchmarker.Run
Target "InternalizeDependencies" Build.ILRepack
diff --git a/src/Elasticsearch.sln.DotSettings b/src/Elasticsearch.sln.DotSettings
index c0aa08ce146..4bfa3de5193 100644
--- a/src/Elasticsearch.sln.DotSettings
+++ b/src/Elasticsearch.sln.DotSettings
@@ -470,6 +470,7 @@
True
True
True
+ True
True
True
False
diff --git a/src/Tests/Tests.Benchmarking/BenchmarkProgram.cs b/src/Tests/Tests.Benchmarking/BenchmarkProgram.cs
index 8ea77455bb5..9b9973c5f3e 100644
--- a/src/Tests/Tests.Benchmarking/BenchmarkProgram.cs
+++ b/src/Tests/Tests.Benchmarking/BenchmarkProgram.cs
@@ -1,31 +1,113 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Reflection;
using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Configs;
+using BenchmarkDotNet.Diagnosers;
+using BenchmarkDotNet.Environments;
+using BenchmarkDotNet.Exporters;
+using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
+using Elastic.BenchmarkDotNetExporter;
+using LibGit2Sharp;
+using Tests.Benchmarking.Framework;
+using RunMode = BenchmarkDotNet.Jobs.RunMode;
namespace Tests.Benchmarking
{
public static class Program
{
- public static int Main(string[] arguments)
+ private static string Commit { get; }
+ private static string CommitMessage { get; }
+ private static string Branch { get; }
+ private static string Repository { get; }
+
+ static Program()
{
- Console.WriteLine("Running Benchmarking.");
- if (arguments.Count() >= 1 && arguments[0].Equals("non-interactive", StringComparison.OrdinalIgnoreCase))
+ var dirInfo = new DirectoryInfo(Environment.CurrentDirectory);
+ while(dirInfo != dirInfo.Root && !Directory.Exists(Path.Combine(dirInfo.FullName, ".git")))
+ dirInfo = dirInfo.Parent;
+ if (!Directory.Exists(Path.Combine(dirInfo.FullName, ".git"))) Environment.Exit(2);
+
+ Console.WriteLine(dirInfo.FullName);
+ using (var repos = new Repository(dirInfo.FullName))
{
- Console.WriteLine("Running in Non-Interactive mode.");
- foreach (var benchmarkType in GetBenchmarkTypes()) BenchmarkRunner.Run(benchmarkType);
+ Commit = repos.Head.Tip.Sha;
+ CommitMessage = repos.Head.Tip.Message?.Trim(' ', '\t', '\r', '\n');
+ Branch = repos.Head.FriendlyName;
+ var remoteName = repos.Head.RemoteName;
+ Repository =
+ repos.Network.Remotes.FirstOrDefault(r => r.Name == remoteName)?.Url
+ ?? repos.Network.Remotes.FirstOrDefault()?.Url;
+ }
+ }
- return 0;
+ public static int Main(string[] arguments)
+ {
+ Console.WriteLine($"Tests.Benchmarking: [{Branch}]@({Commit}) on {Repository} : {CommitMessage} - ");
+ var config = CreateDefaultConfig();
+ if (arguments.Any() && arguments[0].Equals("--all", StringComparison.OrdinalIgnoreCase))
+ {
+ Console.WriteLine("Running all the benchmarks");
+ return RunAllBenchmarks(config, arguments.Skip(1).ToArray());
}
- Console.WriteLine("Running in Interactive mode.");
+ Console.WriteLine("Running the interactive benchmark switcher.");
var benchmarkSwitcher = new BenchmarkSwitcher(GetBenchmarkTypes());
- benchmarkSwitcher.Run(arguments);
+ config = config.With(MarkdownExporter.GitHub);
+ benchmarkSwitcher.Run(arguments, config);
return 0;
}
+ private static IConfig CreateDefaultConfig()
+ {
+ var jobs = new[]
+ {
+ Job.ShortRun.With(Runtime.Core).With(Jit.RyuJit),
+ Job.ShortRun.With(Runtime.Clr).With(Jit.RyuJit),
+ Job.ShortRun.With(Runtime.Clr).With(Jit.LegacyJit),
+ };
+ var config = DefaultConfig.Instance
+ .With(jobs)
+ .With(MemoryDiagnoser.Default);
+ return config;
+ }
+
+ private static int RunAllBenchmarks(IConfig config, string[] arguments)
+ {
+ var url = arguments.Length > 0 ? arguments[0] : null;
+ var username = arguments.Length > 1 ? arguments[1] : null;
+ var password = arguments.Length > 2 ? arguments[2] : null;
+
+ Console.WriteLine("Running in Non-Interactive mode.");
+
+ var exporter = CreateElasticsearchExporter(url, username, password);
+ foreach (var benchmarkType in GetBenchmarkTypes())
+ {
+ if (exporter != null) config = config.With(exporter);
+ BenchmarkRunner.Run(benchmarkType, config);
+ }
+
+ return 0;
+ }
+
+ private static ElasticsearchBenchmarkExporter CreateElasticsearchExporter(string url, string username, string password)
+ {
+ if (string.IsNullOrWhiteSpace(url)) return null;
+ var options = new ElasticsearchBenchmarkExporterOptions(url)
+ {
+ Username = username,
+ Password = password,
+ GitCommitSha = Commit,
+ GitBranch = Branch,
+ GitCommitMessage = CommitMessage,
+ GitRepositoryIdentifier = Repository
+ };
+ return new ElasticsearchBenchmarkExporter(options);
+ }
+
private static Type[] GetBenchmarkTypes()
{
diff --git a/src/Tests/Tests.Benchmarking/BulkDeserializationBenchmarkTests.cs b/src/Tests/Tests.Benchmarking/BulkDeserializationBenchmarkTests.cs
index 3e31c05681e..3de3613be73 100644
--- a/src/Tests/Tests.Benchmarking/BulkDeserializationBenchmarkTests.cs
+++ b/src/Tests/Tests.Benchmarking/BulkDeserializationBenchmarkTests.cs
@@ -46,44 +46,44 @@ public BulkResponse MediumResponse()
return Client.RequestResponseSerializer.Deserialize(ms);
}
- [Benchmark(Description = "deserialize 1,000 items in bulk response")]
- public BulkResponse LargeResponse()
- {
- using (var ms = new MemoryStream(_largeResponse))
- return Client.RequestResponseSerializer.Deserialize(ms);
- }
-
- [Benchmark(Description = "deserialize 100,000 items in bulk response")]
- public BulkResponse HugeResponse()
- {
- using (var ms = new MemoryStream(_hugeResponse))
- return Client.RequestResponseSerializer.Deserialize(ms);
- }
-
- [Benchmark(Description = "deserialize 100,000 items in bulk response")]
- public BulkResponse HugeResponseWithStream()
- {
- using (var ms = new JsonTextReader(new StreamReader(new MemoryStream(_hugeResponse))))
- return _jsonSerializer.Deserialize(ms);
- }
-
- [Benchmark(Description = "deserialize 100,000 items in bulk string response")]
- public BulkResponse HugeResponseWithString()
- {
- using (var reader = new JsonTextReader(new StringReader(Encoding.UTF8.GetString(_hugeResponse))))
- return _jsonSerializer.Deserialize(reader);
- }
-
- [Benchmark(Description = "Baseline", Baseline = true)]
- public BulkResponse Baseline()
- {
- using (var reader = new JsonTextReader(new StreamReader(new MemoryStream(_hugeResponse))))
- {
- while (reader.Read()) { }
-
- return new BulkResponse();
- }
- }
+// [Benchmark(Description = "deserialize 1,000 items in bulk response")]
+// public BulkResponse LargeResponse()
+// {
+// using (var ms = new MemoryStream(_largeResponse))
+// return Client.RequestResponseSerializer.Deserialize(ms);
+// }
+//
+// [Benchmark(Description = "deserialize 100,000 items in bulk response")]
+// public BulkResponse HugeResponse()
+// {
+// using (var ms = new MemoryStream(_hugeResponse))
+// return Client.RequestResponseSerializer.Deserialize(ms);
+// }
+//
+// [Benchmark(Description = "deserialize 100,000 items in bulk response")]
+// public BulkResponse HugeResponseWithStream()
+// {
+// using (var ms = new JsonTextReader(new StreamReader(new MemoryStream(_hugeResponse))))
+// return _jsonSerializer.Deserialize(ms);
+// }
+//
+// [Benchmark(Description = "deserialize 100,000 items in bulk string response")]
+// public BulkResponse HugeResponseWithString()
+// {
+// using (var reader = new JsonTextReader(new StringReader(Encoding.UTF8.GetString(_hugeResponse))))
+// return _jsonSerializer.Deserialize(reader);
+// }
+//
+// [Benchmark(Description = "Baseline", Baseline = true)]
+// public BulkResponse Baseline()
+// {
+// using (var reader = new JsonTextReader(new StreamReader(new MemoryStream(_hugeResponse))))
+// {
+// while (reader.Read()) { }
+//
+// return new BulkResponse();
+// }
+// }
private static object BulkItemResponse() => new
{
diff --git a/src/Tests/Tests.Benchmarking/FieldResolverBenchmarkTests.cs b/src/Tests/Tests.Benchmarking/FieldResolverBenchmarkTests.cs
deleted file mode 100644
index 575ece741df..00000000000
--- a/src/Tests/Tests.Benchmarking/FieldResolverBenchmarkTests.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using BenchmarkDotNet.Attributes;
-using Nest;
-using Tests.Benchmarking.Framework;
-using Tests.Domain;
-
-namespace Tests.Benchmarking
-{
- [BenchmarkConfig(100)]
- public class FieldResolverBenchmarkTests
- {
- private static readonly Field InferredField = Infer.Field(p => p.Name);
- private static readonly Field PropertyField = typeof(Project).GetProperty(nameof(Project.Name));
- private static readonly Field StringField = "Name";
- private FieldResolver _expressionResolver;
- private NoncachingFieldResolver _nonCachingExpressionResolver;
- private NoncachingFieldResolver _nonCachingPropertyResolver;
- private NoncachingFieldResolver _nonCachingStringResolver;
- private FieldResolver _propertyResolver;
- private FieldResolver _stringResolver;
-
- [GlobalSetup]
- public void Setup()
- {
- _expressionResolver = new FieldResolver(new ConnectionSettings());
- _propertyResolver = new FieldResolver(new ConnectionSettings());
- _stringResolver = new FieldResolver(new ConnectionSettings());
- _nonCachingExpressionResolver = new NoncachingFieldResolver(new ConnectionSettings());
- _nonCachingPropertyResolver = new NoncachingFieldResolver(new ConnectionSettings());
- _nonCachingStringResolver = new NoncachingFieldResolver(new ConnectionSettings());
- }
-
- [Benchmark]
- public string NonCachedFieldUsingExpression() => _nonCachingExpressionResolver.Resolve(InferredField);
-
- [Benchmark]
- public string CachedFieldUsingExpression() => _expressionResolver.Resolve(InferredField);
-
- [Benchmark]
- public string NonCachedFieldUsingPropertyInfo() => _nonCachingPropertyResolver.Resolve(PropertyField);
-
- [Benchmark]
- public string CachedFieldUsingPropertyInfo() => _propertyResolver.Resolve(PropertyField);
-
- [Benchmark(Baseline = true)]
- public string NonCachedFieldUsingString() => _nonCachingStringResolver.Resolve(StringField);
-
- [Benchmark]
- public string CachedFieldUsingString() => _stringResolver.Resolve(StringField);
- }
-}
diff --git a/src/Tests/Tests.Benchmarking/Framework/BenchmarkConfig.cs b/src/Tests/Tests.Benchmarking/Framework/BenchmarkConfig.cs
index 87c153b4110..22269897bb4 100644
--- a/src/Tests/Tests.Benchmarking/Framework/BenchmarkConfig.cs
+++ b/src/Tests/Tests.Benchmarking/Framework/BenchmarkConfig.cs
@@ -1,86 +1,11 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using BenchmarkDotNet.Configs;
-using BenchmarkDotNet.Diagnosers;
-using BenchmarkDotNet.Environments;
-using BenchmarkDotNet.Exporters;
-using BenchmarkDotNet.Jobs;
-using BenchmarkDotNet.Loggers;
-using BenchmarkDotNet.Reports;
-using Newtonsoft.Json;
namespace Tests.Benchmarking.Framework
{
- public class CustomJsonExporter : ExporterBase
+ public class BenchmarkConfigAttribute : Attribute
{
- protected override string FileExtension => "json";
+ public int RunCount { get; }
- protected override string FileNameSuffix => "-custom";
-
- public override void ExportToLog(Summary summary, ILogger logger)
- {
- var environmentInfo = new
- {
- HostEnvironmentInfo.BenchmarkDotNetCaption,
- summary.HostEnvironmentInfo.BenchmarkDotNetVersion,
- OsVersion = summary.HostEnvironmentInfo.OsVersion.Value,
- summary.HostEnvironmentInfo.CpuInfo.Value.ProcessorName,
- summary.HostEnvironmentInfo.CpuInfo.Value.PhysicalCoreCount,
- summary.HostEnvironmentInfo.RuntimeVersion,
- summary.HostEnvironmentInfo.Architecture,
- summary.HostEnvironmentInfo.HasAttachedDebugger,
- summary.HostEnvironmentInfo.HasRyuJit,
- summary.HostEnvironmentInfo.Configuration,
- summary.HostEnvironmentInfo.JitModules,
- DotNetCliVersion = summary.HostEnvironmentInfo.DotNetSdkVersion.Value,
- summary.HostEnvironmentInfo.ChronometerFrequency,
- HardwareTimerKind = summary.HostEnvironmentInfo.HardwareTimerKind.ToString()
- };
-
- var benchmarks = summary.Reports.Select(r =>
- {
- var data = new Dictionary
- {
- { "DisplayInfo", r.BenchmarkCase.DisplayInfo },
- { "Namespace", r.BenchmarkCase.Descriptor.Type.Namespace },
- { "Type", r.BenchmarkCase.Descriptor.Type.Name },
- { "Method", r.BenchmarkCase.Descriptor.WorkloadMethod.Name },
- { "MethodTitle", r.BenchmarkCase.Descriptor.WorkloadMethod.Name },
- { "Parameters", r.BenchmarkCase.Parameters.PrintInfo },
- { "Statistics", r.ResultStatistics },
- { "Memory", r.GcStats }
- };
-
- return data;
- });
-
- logger.WriteLine(JsonConvert.SerializeObject(new Dictionary
- {
- { "Title", summary.Title },
- { "TotalTime", summary.TotalTime },
- { "HostEnvironmentInfo", environmentInfo },
- { "Benchmarks", benchmarks }
- }));
- }
- }
-
- public class BenchmarkConfigAttribute : Attribute, IConfigSource
- {
- public BenchmarkConfigAttribute(int runCount = 1)
- {
- var jobs = new[]
- {
- Job.Dry.With(Runtime.Core).With(Jit.RyuJit).WithIterationCount(runCount),
- Job.Dry.With(Runtime.Clr).With(Jit.RyuJit).WithIterationCount(runCount),
- Job.Dry.With(Runtime.Clr).With(Jit.LegacyJit).WithIterationCount(runCount)
- };
- Config = DefaultConfig.Instance
- .With(jobs)
- .With(new CustomJsonExporter())
- .With(MemoryDiagnoser.Default);
- }
-
- public IConfig Config { get; }
+ public BenchmarkConfigAttribute(int runCount = 1) => RunCount = runCount;
}
}
diff --git a/src/Tests/Tests.Benchmarking/NoncachingFieldResolver.cs b/src/Tests/Tests.Benchmarking/NoncachingFieldResolver.cs
deleted file mode 100644
index 8524768a044..00000000000
--- a/src/Tests/Tests.Benchmarking/NoncachingFieldResolver.cs
+++ /dev/null
@@ -1,167 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Globalization;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Text;
-using Nest;
-
-namespace Tests.Benchmarking
-{
- public class NoncachingFieldResolver
- {
- private readonly IConnectionSettingsValues _settings;
-
- public NoncachingFieldResolver(IConnectionSettingsValues settings) => _settings = settings;
-
- public string Resolve(Field field)
- {
- var name = ResolveFieldName(field);
- if (field.Boost.HasValue) name += $"^{field.Boost.Value.ToString(CultureInfo.InvariantCulture)}";
- return name;
- }
-
- internal static bool IsConditionless(Field field) =>
- field == null || string.IsNullOrEmpty(field.Name) && field.Expression == null && field.Property == null;
-
- internal static bool IsConditionless(PropertyName property) =>
- property == null || string.IsNullOrEmpty(property.Name) && property.Expression == null && property.Property == null;
-
- private string ResolveFieldName(Field field)
- {
- if (IsConditionless(field)) return null;
- if (!string.IsNullOrEmpty(field.Name)) return field.Name;
- if (field.Expression != null && !field.CachableExpression) return Resolve(field.Expression, field.Property);
-
- var fieldName = Resolve(field.Expression, field.Property);
- return fieldName;
- }
-
- public string Resolve(PropertyName property)
- {
- if (IsConditionless(property)) return null;
- if (!string.IsNullOrEmpty(property.Name)) return property.Name;
-
- if (property.Expression != null && !property.CacheableExpression) return Resolve(property.Expression, property.Property);
-
- var propertyName = Resolve(property.Expression, property.Property, true);
- return propertyName;
- }
-
- private string Resolve(Expression expression, MemberInfo member, bool toLastToken = false)
- {
- var visitor = new FieldExpressionVisitor(_settings);
- var name = expression != null
- ? visitor.Resolve(expression, toLastToken)
- : member != null
- ? visitor.Resolve(member)
- : null;
-
- if (name == null)
- throw new ArgumentException("Name resolved to null for the given Expression or MemberInfo.");
-
- return name;
- }
-
- internal class FieldExpressionVisitor : ExpressionVisitor
- {
- private readonly IConnectionSettingsValues _settings;
- private readonly Stack _stack = new Stack();
-
- public FieldExpressionVisitor(IConnectionSettingsValues settings) => _settings = settings;
-
- public string Resolve(Expression expression, bool toLastToken = false)
- {
- Visit(expression);
- if (toLastToken) return Enumerable.Last(_stack);
-
- return Enumerable.Aggregate(_stack, new StringBuilder(),
- (sb, name) =>
- (sb.Length > 0 ? sb.Append(".") : sb).Append(name))
- .ToString();
- }
-
- public string Resolve(MemberInfo info)
- {
- if (info == null)
- return null;
-
- var name = info.Name;
-
- if (_settings.PropertyMappings.TryGetValue(info, out var propertyMapping))
- return propertyMapping.Name;
-
- var att = ElasticsearchPropertyAttributeBase.From(info);
- if (att != null && !string.IsNullOrEmpty(att.Name))
- return att.Name;
-
- return _settings.PropertyMappingProvider?.CreatePropertyMapping(info)?.Name ?? _settings.DefaultFieldNameInferrer(name);
- }
-
- protected override Expression VisitMember(MemberExpression expression)
- {
- if (_stack == null) return base.VisitMember(expression);
-
- var name = Resolve(expression.Member);
- _stack.Push(name);
- return base.VisitMember(expression);
- }
-
- protected override Expression VisitMethodCall(MethodCallExpression methodCall)
- {
- if (methodCall.Method.Name == "Suffix" && methodCall.Arguments.Any())
- {
- VisitConstantOrVariable(methodCall, _stack);
- var callingMember = new ReadOnlyCollection(
- new List { { methodCall.Arguments.First() } }
- );
- Visit(callingMember);
- return methodCall;
- }
- else if (methodCall.Method.Name == "get_Item" && methodCall.Arguments.Any())
- {
- var t = methodCall.Object.Type;
- var isDict =
- typeof(IDictionary).IsAssignableFrom(t)
- || typeof(IDictionary<,>).IsAssignableFrom(t)
- || t.GetTypeInfo().IsGenericType && t.GetGenericTypeDefinition() == typeof(IDictionary<,>);
-
- if (!isDict) return base.VisitMethodCall(methodCall);
-
- VisitConstantOrVariable(methodCall, _stack);
- Visit(methodCall.Object);
- return methodCall;
- }
- else if (IsLinqOperator(methodCall.Method))
- {
- for (var i = 1; i < methodCall.Arguments.Count; i++) Visit(methodCall.Arguments[i]);
- Visit(methodCall.Arguments[0]);
- return methodCall;
- }
- return base.VisitMethodCall(methodCall);
- }
-
- private static void VisitConstantOrVariable(MethodCallExpression methodCall, Stack stack)
- {
- var lastArg = methodCall.Arguments.Last();
- var constantExpression = lastArg as ConstantExpression;
- var value = constantExpression != null
- ? constantExpression.Value.ToString()
- : Expression.Lambda(lastArg).Compile().DynamicInvoke().ToString();
- stack.Push(value);
- }
-
- private static bool IsLinqOperator(MethodInfo methodInfo)
- {
- if (methodInfo.DeclaringType != typeof(Queryable) && methodInfo.DeclaringType != typeof(Enumerable))
- return false;
-
- return methodInfo.GetCustomAttribute() != null;
- }
- }
- }
-}
diff --git a/src/Tests/Tests.Benchmarking/PostDataBenchmarks.cs b/src/Tests/Tests.Benchmarking/PostDataBenchmarks.cs
deleted file mode 100644
index e0eac96196c..00000000000
--- a/src/Tests/Tests.Benchmarking/PostDataBenchmarks.cs
+++ /dev/null
@@ -1,437 +0,0 @@
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using BenchmarkDotNet.Attributes;
-using Elasticsearch.Net;
-using Nest;
-using Newtonsoft.Json.Linq;
-using Tests.Benchmarking.Framework;
-
-namespace Tests.Benchmarking
-{
- [BenchmarkConfig(1000)]
- public class PostDataBenchmarks
- {
- private readonly PostData _postDataOfBytes;
-
-
- private readonly PostData _postDataOfBytesDisableDirectStreaming;
- private readonly PostData _postDataOfCollectionOfComplexObjects;
- private readonly PostData _postDataOfCollectionOfComplexObjectsDisableDirectStreaming;
- private readonly PostData _postDataOfCollectionOfSimpleObjects;
- private readonly PostData _postDataOfCollectionOfSimpleObjectsDisableDirectStreaming;
- private readonly PostData _postDataOfCollectionOfStrings;
- private readonly PostData _postDataOfCollectionOfStringsDisableDirectStreaming;
- private readonly PostData _postDataOfComplexObject;
- private readonly PostData _postDataOfComplexObjectDisableDirectStreaming;
- private readonly PostData _postDataOfSimpleObject;
- private readonly PostData _postDataOfSimpleObjectDisableDirectStreaming;
- private readonly PostData _postDataOfString;
- private readonly PostData _postDataOfStringDisableDirectStreaming;
- private readonly byte[] bytes = Encoding.UTF8.GetBytes("{my_property=\"value\"}");
- private readonly List
\ No newline at end of file