Skip to content

Optimize findClosestMatch complexity#11263

Merged
rchiodo merged 1 commit intomicrosoft:mainfrom
Zaczero:zaczero/fcm
Feb 3, 2026
Merged

Optimize findClosestMatch complexity#11263
rchiodo merged 1 commit intomicrosoft:mainfrom
Zaczero:zaczero/fcm

Conversation

@Zaczero
Copy link
Copy Markdown
Contributor

@Zaczero Zaczero commented Feb 2, 2026

This change improved the performance on openstreetmap-ng codebase by about 6%.

14.5s → 13.6s (-6.6% ± 0.6%)

  • Old algorithm: O(n) per query (n = map.size), even though only a handful of ancestors could possibly match.
  • New algorithm: O(depth) map lookups (depth = number of path segments, usually small), and returns as soon as the best match is found.

The correctness is preserved because “best match” is defined purely in terms of ancestor relationship + maximum path length, and walking ancestors from deepest to root returns the same maximum-length ancestor when present.

@Zaczero

This comment was marked as off-topic.

private _findClosestMatch(uri: Uri, map: UriMap<MappedEntry>): MappedEntry | undefined {
// Search through the map of directories to find the closest match. The
// closest match is the longest path that is a parent of the uri.
let entry = map.get(uri);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You changed the algorithm. It's supposed to find the longest match in the list of entries, not keep searching until it finds one that matches the beginning of the URI.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please show me an example? For what kind of data would it produce different results?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry you're right. I always get isChild backwards. isChild is doing the same thing as your getEntry and getDirectory is doing.

@github-actions

This comment has been minimized.

@Zaczero Zaczero marked this pull request as draft February 2, 2026 18:17
@Zaczero Zaczero marked this pull request as ready for review February 2, 2026 18:22
@Zaczero Zaczero requested a review from rchiodo February 2, 2026 18:22
@Zaczero
Copy link
Copy Markdown
Contributor Author

Zaczero commented Feb 2, 2026

I was checking for possible regressions and I noticed that packages/pyright-internal/src/common/uri/constantUri.ts has isRoot that always returns false. So I updated the stop condition to work universally and abort when the URI is no longer changing.

@rchiodo rchiodo merged commit 74ec0f5 into microsoft:main Feb 3, 2026
23 of 24 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 3, 2026

Diff from mypy_primer, showing the effect of this PR on open source code:

sympy (https://github.com/sympy/sympy)
+   .../projects/sympy/sympy/solvers/ode/hypergeometric.py:246:67 - error: Operator "**" not supported for types "Basic" and "Literal[2]" (reportOperatorIssue)
-   .../projects/sympy/sympy/solvers/ode/lie_group.py:618:61 - error: Operator "-" not supported for type "Unknown | Basic" (reportOperatorIssue)
-     Attribute "pop" is unknown (reportAttributeAccessIssue)
-   .../projects/sympy/sympy/solvers/ode/ode.py:609:22 - error: Cannot access attribute "pop" for class "tuple[()]"
-     Attribute "pop" is unknown (reportAttributeAccessIssue)
-   .../projects/sympy/sympy/solvers/ode/ode.py:609:22 - error: Cannot access attribute "pop" for class "tuple[str, ...]"
-   .../projects/sympy/sympy/solvers/ode/systems.py:1213:26 - error: Argument of type "dict[str, str | Unknown | Pow | bool | Symbol]" cannot be assigned to parameter "m" of type "Iterable[tuple[str, str]]" in function "update"
+   .../projects/sympy/sympy/solvers/ode/systems.py:1213:26 - error: Argument of type "dict[str, str | Unknown | Expr | bool | Symbol]" cannot be assigned to parameter "m" of type "Iterable[tuple[str, str]]" in function "update"
+   .../projects/sympy/sympy/stats/crv_types.py:2542:9 - error: Method "_cdf" overrides class "SingleContinuousDistribution" in an incompatible manner
+     Return type mismatch: base method returns type "None", override returns type "ComplexInfinity | NaN | Rational | Zero | Infinity | NegativeInfinity | Float | Unknown"
+       Type "ComplexInfinity | NaN | Rational | Zero | Infinity | NegativeInfinity | Float | Unknown" is not assignable to type "None"
+         "ComplexInfinity" is not assignable to "None" (reportIncompatibleMethodOverride)
+   .../projects/sympy/sympy/stats/crv_types.py:2721:9 - error: Method "_cdf" overrides class "SingleContinuousDistribution" in an incompatible manner
+     Return type mismatch: base method returns type "None", override returns type "Expr | NaN | ComplexInfinity | Rational | Zero | Infinity | NegativeInfinity | Float | Unknown | One | NegativeOne | Integer"
+       Type "Expr | NaN | ComplexInfinity | Rational | Zero | Infinity | NegativeInfinity | Float | Unknown | One | NegativeOne | Integer" is not assignable to type "None"
+         "Expr" is not assignable to "None" (reportIncompatibleMethodOverride)
+   .../projects/sympy/sympy/stats/frv_types.py:138:17 - error: Argument of type "NaN | ComplexInfinity | Rational | Zero | Infinity | NegativeInfinity | Float | Unknown | Expr" cannot be assigned to parameter "value" of type "int" in function "__setitem__"
+     Type "NaN | ComplexInfinity | Rational | Zero | Infinity | NegativeInfinity | Float | Unknown | Expr" is not assignable to type "int"
+       "Expr" is not assignable to "int" (reportArgumentType)
+   .../projects/sympy/sympy/stats/symbolic_probability.py:74:9 - error: Method "doit" overrides class "Basic" in an incompatible manner
+     Return type mismatch: base method returns type "Basic", override returns type "Unknown | Any | BernoulliDistribution | Probability | Zero | One | tuple[Unknown, ...] | Sum | Expr | ZeroMatrix | NaN | Piecewise | Basic | ComplexInfinity | Float | Infinity | Integer | Lambda | Mul | NegativeInfinity | NegativeOne | Number | Rational | Integral | Literal[0]"
+       Type "Unknown | Any | BernoulliDistribution | Probability | Zero | One | tuple[Unknown, ...] | Sum | Expr | ZeroMatrix | NaN | Piecewise | Basic | ComplexInfinity | Float | Infinity | Integer | Lambda | Mul | NegativeInfinity | NegativeOne | Number | Rational | Integral | Literal[0]" is not assignable to type "Basic"
+         "Literal[0]" is not assignable to "Basic" (reportIncompatibleMethodOverride)
+   .../projects/sympy/sympy/stats/tests/test_continuous_rv.py:1542:12 - error: No overloads for "simplify" match the provided arguments (reportCallIssue)
+   .../projects/sympy/sympy/stats/tests/test_continuous_rv.py:1542:21 - error: Argument of type "Unknown | Any | BernoulliDistribution | Probability | Zero | One | tuple[Unknown, ...] | Sum | Expr | ZeroMatrix | NaN | Piecewise | Basic | ComplexInfinity | Float | Infinity | Integer | Lambda | Mul | NegativeInfinity | NegativeOne | Number | Rational | Integral | Literal[0]" cannot be assigned to parameter "expr" of type "Basic" in function "simplify"
+     Type "Unknown | Any | BernoulliDistribution | Probability | Zero | One | tuple[Unknown, ...] | Sum | Expr | ZeroMatrix | NaN | Piecewise | Basic | ComplexInfinity | Float | Infinity | Integer | Lambda | Mul | NegativeInfinity | NegativeOne | Number | Rational | Integral | Literal[0]" is not assignable to type "Basic"
+       "Literal[0]" is not assignable to "Basic" (reportArgumentType)
+   .../projects/sympy/sympy/stats/tests/test_continuous_rv.py:1544:12 - error: No overloads for "simplify" match the provided arguments (reportCallIssue)
+   .../projects/sympy/sympy/stats/tests/test_continuous_rv.py:1544:21 - error: Argument of type "Unknown | Any | BernoulliDistribution | Probability | Zero | One | tuple[Unknown, ...] | Sum | Expr | ZeroMatrix | NaN | Piecewise | Basic | ComplexInfinity | Float | Infinity | Integer | Lambda | Mul | NegativeInfinity | NegativeOne | Number | Rational | Integral | Literal[0]" cannot be assigned to parameter "expr" of type "Basic" in function "simplify"
+     Type "Unknown | Any | BernoulliDistribution | Probability | Zero | One | tuple[Unknown, ...] | Sum | Expr | ZeroMatrix | NaN | Piecewise | Basic | ComplexInfinity | Float | Infinity | Integer | Lambda | Mul | NegativeInfinity | NegativeOne | Number | Rational | Integral | Literal[0]" is not assignable to type "Basic"
+       "Literal[0]" is not assignable to "Basic" (reportArgumentType)
+   .../projects/sympy/sympy/stats/tests/test_continuous_rv.py:1549:12 - error: No overloads for "simplify" match the provided arguments (reportCallIssue)
+   .../projects/sympy/sympy/stats/tests/test_continuous_rv.py:1549:21 - error: Argument of type "Unknown | Any | BernoulliDistribution | Probability | Zero | One | tuple[Unknown, ...] | Sum | Expr | ZeroMatrix | NaN | Piecewise | Basic | ComplexInfinity | Float | Infinity | Integer | Lambda | Mul | NegativeInfinity | NegativeOne | Number | Rational | Integral | Literal[0]" cannot be assigned to parameter "expr" of type "Basic" in function "simplify"
+     Type "Unknown | Any | BernoulliDistribution | Probability | Zero | One | tuple[Unknown, ...] | Sum | Expr | ZeroMatrix | NaN | Piecewise | Basic | ComplexInfinity | Float | Infinity | Integer | Lambda | Mul | NegativeInfinity | NegativeOne | Number | Rational | Integral | Literal[0]" is not assignable to type "Basic"
+       "Literal[0]" is not assignable to "Basic" (reportArgumentType)
-   .../projects/sympy/sympy/stats/tests/test_finite_rv.py:33:23 - error: Operator "/" not supported for types "Unknown | Any | BernoulliDistribution | Probability | Zero | One | Expr | Float | ComplexInfinity | NaN | Rational | Infinity | NegativeInfinity | NotImplementedType | tuple[Unknown, ...] | Sum | ZeroMatrix | Piecewise | Basic | Integer | Lambda | Mul | NegativeOne | Number | Integral | Literal[0]" and "Unknown | Any | BernoulliDistribution | Probability | Zero | One | Expr | Float | ComplexInfinity | NaN | Rational | Infinity | NegativeInfinity | NotImplementedType | tuple[Unknown, ...] | Sum | ZeroMatrix | Piecewise | Basic | Integer | Lambda | Mul | NegativeOne | Number | Integral | Literal[0]"
+   .../projects/sympy/sympy/stats/tests/test_finite_rv.py:33:23 - error: Operator "/" not supported for types "Unknown | Any | BernoulliDistribution | Probability | Zero | One | tuple[Unknown, ...] | Sum | Expr | ZeroMatrix | NaN | Piecewise | Basic | ComplexInfinity | Float | Infinity | Integer | Lambda | Mul | NegativeInfinity | NegativeOne | Number | Rational | Integral | Literal[0]" and "Unknown | Any | BernoulliDistribution | Probability | Zero | One | tuple[Unknown, ...] | Sum | Expr | ZeroMatrix | NaN | Piecewise | Basic | ComplexInfinity | Float | Infinity | Integer | Lambda | Mul | NegativeInfinity | NegativeOne | Number | Rational | Integral | Literal[0]"
-   .../projects/sympy/sympy/stats/tests/test_finite_rv.py:34:23 - error: Operator "*" not supported for types "Unknown | Any | BernoulliDistribution | Probability | Zero | One | Expr | Float | ComplexInfinity | NaN | Rational | Infinity | NegativeInfinity | NotImplementedType | tuple[Unknown, ...] | Sum | ZeroMatrix | Piecewise | Basic | Integer | Lambda | Mul | NegativeOne | Number | Integral | Literal[0]" and "Unknown | Any | BernoulliDistribution | Probability | Zero | One | Expr | Float | ComplexInfinity | NaN | Rational | Infinity | NegativeInfinity | NotImplementedType | tuple[Unknown, ...] | Sum | ZeroMatrix | Piecewise | Basic | Integer | Lambda | Mul | NegativeOne | Number | Integral | Literal[0]"
+   .../projects/sympy/sympy/stats/tests/test_finite_rv.py:34:23 - error: Operator "*" not supported for types "Unknown | Any | BernoulliDistribution | Probability | Zero | One | tuple[Unknown, ...] | Sum | Expr | ZeroMatrix | NaN | Piecewise | Basic | ComplexInfinity | Float | Infinity | Integer | Lambda | Mul | NegativeInfinity | NegativeOne | Number | Rational | Integral | Literal[0]" and "Unknown | Any | BernoulliDistribution | Probability | Zero | One | tuple[Unknown, ...] | Sum | Expr | ZeroMatrix | NaN | Piecewise | Basic | ComplexInfinity | Float | Infinity | Integer | Lambda | Mul | NegativeInfinity | NegativeOne | Number | Rational | Integral | Literal[0]"
+     Operator "*" not supported for types "BernoulliDistribution" and "tuple[Unknown, ...]"
+     Operator "*" not supported for types "BernoulliDistribution" and "Sum"
-     Operator "*" not supported for types "BernoulliDistribution" and "Float"
+     Operator "*" not supported for types "BernoulliDistribution" and "ZeroMatrix"
-     Operator "*" not supported for types "BernoulliDistribution" and "ComplexInfinity"

... (truncated 1319 lines) ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants