public ContentSerializationPerformanceTests() { this.queryStatisticsDatumVisitor = new(); this.endpoint = Utils.ConfigurationManager.AppSettings["GatewayEndpoint"]; this.authKey = Utils.ConfigurationManager.AppSettings["MasterKey"]; this.cosmosDatabaseId = Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.CosmosDatabaseId"]; this.containerId = Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.ContainerId"]; this.contentSerialization = Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.ContentSerialization"]; this.query = Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.Query"]; this.numberOfIterations = int.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.NumberOfIterations"]); this.warmupIterations = int.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.WarmupIterations"]); this.MaxConcurrency = int.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.MaxConcurrency"]); this.MaxItemCount = int.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.MaxItemCount"]); this.useStronglyTypedIterator = bool.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.UseStronglyTypedIterator"]); }
public void Serialize(TextWriter textWriter, QueryStatisticsDatumVisitor queryStatisticsDatumVisitor, int numberOfIterations, int warmupIterations, bool rawData) { int roundTrips = queryStatisticsDatumVisitor.QueryMetricsList.Count / numberOfIterations; if (rawData == false) { textWriter.WriteLine(roundTrips); List <QueryStatisticsMetrics> noWarmupList = this.EliminateWarmupIterations(queryStatisticsDatumVisitor.QueryMetricsList, roundTrips, warmupIterations); if (roundTrips > 1) { noWarmupList = this.SumOfRoundTrips(roundTrips, noWarmupList); } this.CalculateAverage(noWarmupList).ForEach(textWriter.WriteLine); textWriter.WriteLine(); textWriter.WriteLine(PrintMedian); textWriter.WriteLine(); this.CalculateMedian(noWarmupList.ToList()).ForEach(textWriter.WriteLine); } else { textWriter.WriteLine(); textWriter.WriteLine(PrintQueryMetrics); int roundTripCount = 1; int iterationCount = 1; textWriter.Write(string.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\",\"{5}\",\"{6}\",\"{7}\",\"{8}\",\"{9}\",\"{10}\"," + "\"{11}\",\"{12}\",\"{13}\",\"{14}\",\"{15}\",\"{16}\",\"{17}\"", "Iteration", "RoundTrip", "RetrievedDocumentCount", "RetrievedDocumentSize", "OutputDocumentCount", "OutputDocumentSize", "TotalQueryExecutionTime", "DocumentLoadTime", "DocumentWriteTime", "Created", "ChannelAcquisitionStarted", "Pipelined", "TransitTime", "Received", "Completed", "PocoTime", "GetCosmosElementResponseTime", "EndToEndTime")); textWriter.WriteLine(); foreach (QueryStatisticsMetrics metrics in queryStatisticsDatumVisitor.QueryMetricsList) { if (roundTripCount <= roundTrips) { textWriter.WriteLine(string.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\",\"{5}\",\"{6}\",\"{7}\",\"{8}\",\"{9}\",\"{10}\"," + "\"{11}\",\"{12}\",\"{13}\",\"{14}\",\"{15}\",\"{16}\",\"{17}\"", iterationCount, roundTripCount, metrics.RetrievedDocumentCount, metrics.RetrievedDocumentSize, metrics.OutputDocumentCount, metrics.OutputDocumentSize, metrics.TotalQueryExecutionTime, metrics.DocumentLoadTime, metrics.DocumentWriteTime, metrics.Created, metrics.ChannelAcquisitionStarted, metrics.Pipelined, metrics.TransitTime, metrics.Received, metrics.Completed, metrics.PocoTime, metrics.GetCosmosElementResponseTime, metrics.EndToEndTime)); roundTripCount++; } else { iterationCount++; roundTripCount = 1; textWriter.WriteLine(string.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\",\"{5}\",\"{6}\",\"{7}\",\"{8}\",\"{9}\",\"{10}\"," + "\"{11}\",\"{12}\",\"{13}\",\"{14}\",\"{15}\",\"{16}\",\"{17}\"", iterationCount, roundTripCount, metrics.RetrievedDocumentCount, metrics.RetrievedDocumentSize, metrics.OutputDocumentCount, metrics.OutputDocumentSize, metrics.TotalQueryExecutionTime, metrics.DocumentLoadTime, metrics.DocumentWriteTime, metrics.Created, metrics.ChannelAcquisitionStarted, metrics.Pipelined, metrics.TransitTime, metrics.Received, metrics.Completed, metrics.PocoTime, metrics.GetCosmosElementResponseTime, metrics.EndToEndTime)); roundTripCount++; } } textWriter.WriteLine(); textWriter.WriteLine(PrintBadRequests); foreach (QueryStatisticsMetrics metrics in queryStatisticsDatumVisitor.BadRequestMetricsList) { textWriter.WriteLine(string.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\",\"{5}\"", metrics.BadRequestCreated, metrics.BadRequestChannelAcquisitionStarted, metrics.BadRequestPipelined, metrics.BadRequestTransitTime, metrics.BadRequestReceived, metrics.BadRequestCompleted)); textWriter.WriteLine(); } } textWriter.Flush(); }
public void ReadFromTrace <T>(FeedResponse <T> Response, QueryStatisticsDatumVisitor queryStatisticsDatumVisitor) { ITrace trace = ((CosmosTraceDiagnostics)Response.Diagnostics).Value; //POCO Materialization occurs once per iteration including all the roundtrips List <ITrace> retrieveQueryMetricTraces = this.FindQueryMetrics(trace: trace, nodeNameOrKeyName: ClientParseTimeNode, isKeyName: false); foreach (ITrace queryMetricTrace in retrieveQueryMetricTraces) { queryStatisticsDatumVisitor.AddPocoTime(queryMetricTrace.Duration.TotalMilliseconds); } //Get Cosmos Element Response occurs once per roundtrip for calls with status code 200 List <ITrace> retrieveCosmosElementTraces = this.FindQueryMetrics(trace: trace, nodeNameOrKeyName: ClientDeserializationTimeNode, isKeyName: false); //Query metrics occurs once per roundtrip for calls with status code 200 List <ITrace> backendMetrics = this.FindQueryMetrics(trace: trace, nodeNameOrKeyName: BackendKeyValue, isKeyName: true); //Client metrics occurs once per roundtrip for all status codes List <ITrace> transitMetrics = this.FindQueryMetrics(trace: trace, nodeNameOrKeyName: TransportKeyValue, isKeyName: true, currentNodeName: TransportNodeName); List <Tuple <ITrace, ITrace, ITrace> > backendAndClientMetrics = new(); int i = 0; int j = 0; int k = 0; foreach (ITrace node in transitMetrics) { Debug.Assert(node.Data.Count == 1, "Exactly one transit metric expected"); KeyValuePair <string, object> kvp = node.Data.Single(); Assert.IsInstanceOfType(kvp.Value, typeof(ClientSideRequestStatisticsTraceDatum)); ClientSideRequestStatisticsTraceDatum clientSideRequestStatisticsTraceDatum = (ClientSideRequestStatisticsTraceDatum)kvp.Value; foreach (ClientSideRequestStatisticsTraceDatum.StoreResponseStatistics storeResponse in clientSideRequestStatisticsTraceDatum.StoreResponseStatisticsList) { if (storeResponse.StoreResult.StatusCode == StatusCodes.Ok) { backendAndClientMetrics.Add(Tuple.Create(retrieveCosmosElementTraces[k], backendMetrics[j], transitMetrics[i])); j++; k++; } else { //We add null values to the tuple since status codes other than Ok will not have data for 'Query Metrics' and 'Get Cosmos Element Response' backendAndClientMetrics.Add(Tuple.Create <ITrace, ITrace, ITrace>(null, null, transitMetrics[i])); } } i++; } Debug.Assert(i == transitMetrics.Count, "All 'transit metrics' must be grouped."); Debug.Assert(j == backendMetrics.Count, "All 'backend metrics' must be grouped."); Debug.Assert(k == retrieveCosmosElementTraces.Count, "All 'Get Cosmos Element Response' traces must be grouped."); int l = 1; foreach (Tuple <ITrace, ITrace, ITrace> metrics in backendAndClientMetrics) { if (metrics.Item2 != null) { Debug.Assert(metrics.Item1 == null, "'Get Cosmos Element Response' is null"); queryStatisticsDatumVisitor.AddGetCosmosElementResponseTime(metrics.Item1.Duration.TotalMilliseconds); foreach (KeyValuePair <string, object> kvp in metrics.Item2.Data) { switch (kvp.Value) { case TraceDatum traceDatum: traceDatum.Accept(queryStatisticsDatumVisitor); break; default: Debug.Fail("Unexpected type", $"Type not supported {metrics.Item2.GetType()}"); break; } } //add metrics to the list except for last roundtrip which is taken care of in ContentSerializationPerformanceTest class if (l != backendMetrics.Count) { queryStatisticsDatumVisitor.PopulateMetrics(); } l++; } foreach (KeyValuePair <string, object> kvp in metrics.Item3.Data) { switch (kvp.Value) { case TraceDatum traceDatum: traceDatum.Accept(queryStatisticsDatumVisitor); break; default: Debug.Fail("Unexpected type", $"Type not supported {metrics.Item3.GetType()}"); break; } } } }