question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RequestData.CreatePathWithQueryStrings Performance Optimisation

See original GitHub issue

Further to my PR #4952, I have been reviewing the calling code to look at potential further performance optimisations.

CreatePathWithQueryStrings is called within the RequestData ctor to populate the PathAndQuery property for every instance. The current implementation builds a string after populating NameValueCollection instances from both the global connection config and the request parameters. Eventually, it calls down to the optimised NameValueCollection extension method.

I’ve created a prototype of an optimised version of this method, which rents an oversized Span<char> from the ArrayPool and builds the path and query within that buffer. One key change this includes, is to avoid creating a copy of the existing IConnectionConfigurationValues.QueryStringParameters collection and converting the IRequestParameters.QueryString dictionary to a NameValueCollection. Instead, it performs the conversion of objects from the dictionary directly into the buffer from the pool.

The logic I’ve added so far is simplified for prototyping. It would require some tests to properly validate that it matches (or can match) the existing behaviour. Having benchmarked the prototype for one example request, the potential optimisation is fairly significant.

|                       Method |       Mean |     Error |      StdDev |     Median |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|----------------------------- |-----------:|----------:|------------:|-----------:|-------:|------:|------:|----------:|
|   CreatePathWithQueryStrings | 7,879.6 ns | 390.67 ns | 1,139.61 ns | 7,195.2 ns | 0.3357 |     - |     - |    1464 B |
| CreatePathWithQueryStringsV2 |   648.0 ns |  12.86 ns |    12.03 ns |   648.9 ns | 0.0305 |     - |     - |     128 B |

This equates to a 91.2% reduction in execution time and 91.3% fewer bytes allocated. The final bytes here is pretty much just the creation of the final string, with little or no additional overhead. Given that this occurs per request instance, it seems like a reasonable improvement to go after.

For reference: In the case of the above benchmarks, I used connection settings as follows:

_connectionSettings.GlobalQueryStringParameters(new NameValueCollection
{
    { "allow_no_indices", "false" },
    { "global_key", "thing" } // made up for testing
});

and a request:

new SearchRequestParameters { AllowNoIndices = true, DocValueFields = new[] { "item1" } };

Before investigating this further, I wanted to check if you agree that the risk vs. reward would be considered acceptable in this case. Given it’s a pretty important method for building valid requests, so it’s sensitive should any regressions occur. That said, with sufficient tests, the existing logic is not too complex to thoroughly test before making the change.

There is also a comment from @Mpdreamz in the code…

// TODO This feels like its in the wrong place

I’d consider adding a type (helper) capable of encapsulating the path and query building functionality. If that’s something you’d consider at this point, given that it’s a public API, would there be a preferred strategy for supporting a change. It’s a very functional method, unlikely to be replaced during testing or with alternative runtime implementations.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
russcamcommented, Aug 24, 2020

Thanks for your effort and focus here, @stevejgordon!

1reaction
stevejgordoncommented, Aug 24, 2020

Thanks @Mpdreamz! I’m away on holiday for the remainder of this week, but I’ll continue to take a look at this upon my return. Once I have the core cases working reliably, I’ll get a PR in to review from there.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Introduction to optimizing query performance | BigQuery
Gives an overview of techniques for optimizing query performance in BigQuery. Optimization improves query speed and reduces cost.
Read more >
Best practices design patterns: optimizing Amazon S3 ...
Your applications can easily achieve thousands of transactions per second in request performance when uploading and retrieving storage from Amazon S3.
Read more >
Copy activity performance optimization features
This article outlines the copy activity performance optimization features that you can leverage in Azure Data Factory and Synapse pipelines.
Read more >
Performance optimization with measures in same query?
Solved: Hello! Unfortunately, I have some performance issues with my Power BI. I think this is mostly driven by the hardware I am...
Read more >
Optimizing Performance in Snowflake
Learn how storing similar data together, creating optimized data structures, and defining specialized data sets can improve the performance of queries.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found