Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RedirectRule: opportunity for performance improvement #28883

Closed
paulomorgado opened this issue Dec 28, 2020 · 8 comments
Closed

RedirectRule: opportunity for performance improvement #28883

paulomorgado opened this issue Dec 28, 2020 · 8 comments
Labels
area-middleware Includes: URL rewrite, redirect, response cache/compression, session, and other general middlewares design-proposal This issue represents a design proposal for a different issue, linked in the description Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. Perf
Milestone

Comments

@paulomorgado
Copy link
Contributor

Summary

  1. RedirectRule.ApplyRule is comparing the request path with PathString.Empty, which ends up being a string comparison.
  2. RedirectRule.ApplyRule is boxing a PathString(1)(2).

Motivation and goals

This is in a hot path for applications that use redirections.

Detailed design

  1. Use path.HasValue instead.
  2. Use pathBase.ToUriComponent() instead.
    • A better option would be use UriHelper.BuildRelative. The current implementation doesn't encode the path; only the path base and the query string.
@paulomorgado paulomorgado added the design-proposal This issue represents a design proposal for a different issue, linked in the description label Dec 28, 2020
@Tratcher
Copy link
Member

Have you done any profiling here? This is a class of issue that's unlikely to be addressed unless it shows up as significant in a CPU or memory profile.

  1. HasValue is a similar string comparison (string.IsNullOrEmpty).

    public bool HasValue
    {
    get { return !string.IsNullOrEmpty(Value); }

  2. Are you sure about the boxing? PathString has an implicit string converter that may kick in first. It also overrides the + operator.

    public static implicit operator string(PathString path)
    => path.ToString();

    public static string operator +(PathString left, string? right)
    {
    // This overload exists to prevent the implicit string<->PathString converter from
    // trying to call the PathString+PathString operator for things that are not path strings.
    return string.Concat(left.ToString(), right);
    }

@Tratcher Tratcher added the Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. label Dec 28, 2020
@paulomorgado
Copy link
Contributor Author

If you follow the PathString equality operator, you'll see that it's more than just string.IsNullOrEmpty. And then there's consistency with the rest of the codebase.

You're right about the string.Concat overload being used. It's string.Concat(string, string, string) - there are overloads up to 4 string arguments and the C# compiler prefers the implicit conversion and the overload with string argumetns.

However, the PathString addition operator doesn't apply because the type of the next argument is a sting, not a PathString. It should be, because it's not being encoded like the rest of the components.

@ghost ghost added Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. and removed Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. labels Dec 28, 2020
@Tratcher
Copy link
Member

However, the PathString addition operator doesn't apply because the type of the next argument is a sting, not a PathString. It should be, because it's not being encoded like the rest of the components.

It also has an overload for PathString + string.

@paulomorgado
Copy link
Contributor Author

Got it!

But that means that

pathBase + newPath.Substring(0, split) + query.ToUriComponent()

will end up being

string.Concat(string.Concat(pathBase.ToUriComponent(), newPath.Substring(0, split)), query.ToUriComponent())

Right?

One more string than it needs to be. If we accept that newPath.Substring(0, split) is unavoidable.

@Tratcher
Copy link
Member

Fair point. As you said, UriHelper.BuildRelative would address most of this.

@paulomorgado
Copy link
Contributor Author

Are there any unit tests for this? If so, where?

@paulomorgado
Copy link
Contributor Author

Found! MiddlewareTests.cs

@ghost
Copy link

ghost commented Dec 30, 2020

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

@BrennanConroy BrennanConroy modified the milestones: Backlog, 6.0-preview4 Apr 6, 2021
@ghost ghost locked as resolved and limited conversation to collaborators May 6, 2021
@amcasey amcasey added area-middleware Includes: URL rewrite, redirect, response cache/compression, session, and other general middlewares and removed area-runtime labels Jun 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-middleware Includes: URL rewrite, redirect, response cache/compression, session, and other general middlewares design-proposal This issue represents a design proposal for a different issue, linked in the description Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. Perf
Projects
None yet
Development

No branches or pull requests

6 participants