Skip to content

Perfomance improvement for flex access/egress searches - #3661

Merged
leonardehrenfried merged 15 commits into
opentripplanner:dev-2.xfrom
ibi-group:access-egress-debug
Nov 4, 2021
Merged

leonardehrenfried merged 15 commits into
opentripplanner:dev-2.xfrom
ibi-group:access-egress-debug

Conversation

@leonardehrenfried

@leonardehrenfried leonardehrenfried commented Oct 20, 2021 •

Copy link
Copy Markdown
Member

Summary

We noticed a severe performance problem for flex access/egress searches which would typically be 5-10 times slower than flex direct searches. I also saw that for flex access/egress searches a large number (25000 in my simple case with a hand full of flex routes) of accesses are computed. For this reason I added their number to the debug output.

After a bit of investigation I noticed some performance improvements in #3499 which I extracted into this separate PR. The core of this solution is to stop every flex path from being traversed twice.

Results

Before:

10:20:25.981 DEBUG (DebugTimingAggregator.java:220) ┌  Routing initialization           :     0 ms
10:20:25.982 DEBUG (DebugTimingAggregator.java:220) ├  Direct street routing            :     6 ms
10:20:25.982 DEBUG (DebugTimingAggregator.java:220) │┌ Creating raptor data model       :    30 ms
10:20:25.982 DEBUG (DebugTimingAggregator.java:220) │├ Access routing (25105 accesses)  :  4382 ms
10:20:25.982 DEBUG (DebugTimingAggregator.java:220) │├ Egress routing (432 egresses)    :    83 ms
10:20:25.982 DEBUG (DebugTimingAggregator.java:220) ││ Access/Egress routing            :  4465 ms
10:20:25.982 DEBUG (DebugTimingAggregator.java:220) │├ Main routing                     :   477 ms
10:20:25.982 DEBUG (DebugTimingAggregator.java:220) │├ Creating itineraries             :    10 ms
10:20:25.982 DEBUG (DebugTimingAggregator.java:220) ├┴ Transit routing total            :  4982 ms
10:20:25.982 DEBUG (DebugTimingAggregator.java:220) │  Routing total:                   :  4988 ms
10:20:25.982 DEBUG (DebugTimingAggregator.java:220) ├  Filtering itineraries            :     1 ms
10:20:25.983 DEBUG (DebugTimingAggregator.java:220) ├  Converting model objects         :     0 ms
10:20:25.983 DEBUG (DebugTimingAggregator.java:220) ┴  Request total                    :  4989 ms

After:

10:10:48.699 DEBUG (DebugTimingAggregator.java:220) ┌  Routing initialization           :     0 ms
10:10:48.700 DEBUG (DebugTimingAggregator.java:220) ├  Direct street routing            :     6 ms
10:10:48.700 DEBUG (DebugTimingAggregator.java:220) │┌ Creating raptor data model       :    21 ms
10:10:48.700 DEBUG (DebugTimingAggregator.java:220) │├ Access routing (25117 accesses)  :  2745 ms
10:10:48.700 DEBUG (DebugTimingAggregator.java:220) │├ Egress routing (432 egresses)    :    71 ms
10:10:48.700 DEBUG (DebugTimingAggregator.java:220) ││ Access/Egress routing            :  2816 ms
10:10:48.700 DEBUG (DebugTimingAggregator.java:220) │├ Main routing                     :   475 ms
10:10:48.700 DEBUG (DebugTimingAggregator.java:220) │├ Creating itineraries             :     9 ms
10:10:48.700 DEBUG (DebugTimingAggregator.java:220) ├┴ Transit routing total            :  3321 ms
10:10:48.700 DEBUG (DebugTimingAggregator.java:220) │  Routing total:                   :  3327 ms
10:10:48.700 DEBUG (DebugTimingAggregator.java:220) ├  Filtering itineraries            :     0 ms
10:10:48.700 DEBUG (DebugTimingAggregator.java:220) ├  Converting model objects         :     0 ms
10:10:48.700 DEBUG (DebugTimingAggregator.java:220) ┴  Request total                    :  3327 ms

The improvement is very noticeable but in my view it went only from terrible to bad.

To achieve an even better performance I think we need to dramatically lower the number of accesses being computed.

For example, if I run the same request without flex, the timing looks like this:

10:23:21.951 DEBUG (DebugTimingAggregator.java:220) ┌  Routing initialization           :     0 ms
10:23:21.951 DEBUG (DebugTimingAggregator.java:220) ├  Direct street routing            :     6 ms
10:23:21.951 DEBUG (DebugTimingAggregator.java:220) │┌ Creating raptor data model       :    20 ms
10:23:21.952 DEBUG (DebugTimingAggregator.java:220) │├ Access routing (5 accesses)      :    19 ms
10:23:21.952 DEBUG (DebugTimingAggregator.java:220) │├ Egress routing (432 egresses)    :    77 ms
10:23:21.952 DEBUG (DebugTimingAggregator.java:220) ││ Access/Egress routing            :    97 ms
10:23:21.952 DEBUG (DebugTimingAggregator.java:220) │├ Main routing                     :    57 ms
10:23:21.952 DEBUG (DebugTimingAggregator.java:220) │├ Creating itineraries             :    10 ms
10:23:21.952 DEBUG (DebugTimingAggregator.java:220) ├┴ Transit routing total            :   184 ms
10:23:21.952 DEBUG (DebugTimingAggregator.java:220) │  Routing total:                   :   190 ms
10:23:21.952 DEBUG (DebugTimingAggregator.java:220) ├  Filtering itineraries            :     1 ms
10:23:21.952 DEBUG (DebugTimingAggregator.java:220) ├  Converting model objects         :     0 ms
10:23:21.952 DEBUG (DebugTimingAggregator.java:220) ┴  Request total                    :   191 ms

Unit tests

I would love to write a unit test for flex but I think I need some guidance on how to do it.

Code style

Yes.

Documentation

I've commented the code.

Changelog

Yes

@leonardehrenfried
leonardehrenfried requested a review from a team as a code owner October 20, 2021 08:26
@t2gran t2gran added this to the 2.1 milestone Oct 20, 2021
@t2gran t2gran added the !Improvement A functional improvement or micro feature label Oct 20, 2021
hannesj
hannesj previously approved these changes Oct 20, 2021
@leonardehrenfried

leonardehrenfried commented Oct 27, 2021 •

Copy link
Copy Markdown
Member Author

After having identified the linestring computation as a major bottleneck during the the dev meeting I added a commit which only generates them when they are actually needed, not for the thousands of possible paths that will never be presented to the user. This leads to even more significant performance gains.

Typical stats are these:

09:57:56.815 DEBUG (DebugTimingAggregator.java:220) ┌  Routing initialization           :     0 ms
09:57:56.816 DEBUG (DebugTimingAggregator.java:220) ├  Direct street routing            :     4 ms
09:57:56.816 DEBUG (DebugTimingAggregator.java:220) │┌ Creating raptor data model       :    28 ms
09:57:56.816 DEBUG (DebugTimingAggregator.java:220) │├ Access routing (25117 accesses)  :   953 ms
09:57:56.816 DEBUG (DebugTimingAggregator.java:220) │├ Egress routing (473 egresses)    :    27 ms
09:57:56.816 DEBUG (DebugTimingAggregator.java:220) ││ Access/Egress routing            :   980 ms
09:57:56.816 DEBUG (DebugTimingAggregator.java:220) │├ Main routing                     :   376 ms
09:57:56.816 DEBUG (DebugTimingAggregator.java:220) │├ Creating itineraries             :    10 ms
09:57:56.816 DEBUG (DebugTimingAggregator.java:220) ├┴ Transit routing total            :  1394 ms
09:57:56.816 DEBUG (DebugTimingAggregator.java:220) │  Routing total:                   :  1398 ms
09:57:56.816 DEBUG (DebugTimingAggregator.java:220) ├  Filtering itineraries            :     1 ms
09:57:56.816 DEBUG (DebugTimingAggregator.java:220) ├  Converting model objects         :     0 ms
09:57:56.816 DEBUG (DebugTimingAggregator.java:220) ┴  Request total                    :  1399 ms

Comment thread src/main/resources/logback.xml Outdated
Comment thread src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java Outdated
@leonardehrenfried

Copy link
Copy Markdown
Member Author

I have also implemented what we talked about in the meeting: limiting the distance that a transfer can take when getting in or out of a flex vehicle. If I configure it to be 300m then I typically get the following times:

10:39:46.611 DEBUG (DebugTimingAggregator.java:220) ┌  Routing initialization           :     0 ms
10:39:46.611 DEBUG (DebugTimingAggregator.java:220) ├  Direct street routing            :     3 ms
10:39:46.611 DEBUG (DebugTimingAggregator.java:220) │┌ Creating raptor data model       :    22 ms
10:39:46.611 DEBUG (DebugTimingAggregator.java:220) │├ Access routing (14837 accesses)  :   736 ms
10:39:46.611 DEBUG (DebugTimingAggregator.java:220) │├ Egress routing (473 egresses)    :    38 ms
10:39:46.611 DEBUG (DebugTimingAggregator.java:220) ││ Access/Egress routing            :   736 ms
10:39:46.611 DEBUG (DebugTimingAggregator.java:220) │├ Main routing                     :   186 ms
10:39:46.611 DEBUG (DebugTimingAggregator.java:220) │├ Creating itineraries             :     8 ms
10:39:46.611 DEBUG (DebugTimingAggregator.java:220) ├┴ Transit routing total            :   952 ms
10:39:46.611 DEBUG (DebugTimingAggregator.java:220) │  Routing total:                   :   952 ms
10:39:46.611 DEBUG (DebugTimingAggregator.java:220) ├  Filtering itineraries            :     0 ms
10:39:46.611 DEBUG (DebugTimingAggregator.java:220) ├  Converting model objects         :     1 ms
10:39:46.611 DEBUG (DebugTimingAggregator.java:220) ┴  Request total                    :   953 ms

Comment thread src/main/java/org/opentripplanner/standalone/config/FlexConfig.java Outdated
hannesj
hannesj previously approved these changes Nov 1, 2021
Comment thread src/ext/java/org/opentripplanner/ext/flex/FlexConfig.java Outdated
Comment thread src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java Outdated
Comment thread docs/sandbox/Flex.md Outdated
*Config parameters*

- `maxTransferMeters`: how far should you a passenger be able to walk after getting out of a flex
vehicle and transferring to another one.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

"another one" - Another FLEX or Transit vehicle?

Comment thread docs/sandbox/Flex.md Outdated
Comment on lines +37 to +40
- `maxTransferMeters`: how far should you a passenger be able to walk after getting out of a flex
vehicle and transferring to another one.
This was mainly introduced to improve performance - a lower value means that
the routing is faster.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there an upper limit? This is equivalent to the maxTransferDurationSeconds, so we should use the same unit.

Comment thread src/ext/java/org/opentripplanner/ext/flex/edgetype/FlexTripEdge.java Outdated
Comment thread src/main/java/org/opentripplanner/standalone/config/RouterConfig.java Outdated
t2gran
t2gran previously approved these changes Nov 3, 2021
@leonardehrenfried

leonardehrenfried commented Nov 3, 2021 •

Copy link
Copy Markdown
Member Author

I also took the liberty to also bring the configuration for the vector tiles in line with what @t2gran has requested for the flex one.

@t2gran

t2gran commented Nov 3, 2021

Copy link
Copy Markdown
Member

I also took the liberty also bring the configuration for the vector tiles in line with what @t2gran has requested for the flex one.

The long term goal here is to modularize the code a bit, and hopefully this will make it a bit simpler to infer a dependency-injection framework.

Co-authored-by: Hannes Junnila <hannes.junnila@gmail.com>
@leonardehrenfried
leonardehrenfried merged commit 41bd505 into opentripplanner:dev-2.x Nov 4, 2021
@leonardehrenfried
leonardehrenfried deleted the access-egress-debug branch November 4, 2021 15:04
t2gran pushed a commit that referenced this pull request Nov 4, 2021
@leonardehrenfried leonardehrenfried added IBI Developed by or important for IBI Group and removed IBI test labels Jun 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

IBI Developed by or important for IBI Group !Improvement A functional improvement or micro feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants