Skip to content

faq 299302913

Billy Charlton edited this page Sep 5, 2018 · 2 revisions

Different way of binding of TransitRouter by class directly

by Enoch Lee on 2018-07-03 09:58:03


Dear all,

In every example, the TransitRouter is binded by provider, for instance,

bind(TransitRouter.class).toProvider(SomeTransitRouterFactory.class);

That the transit router is provided by the get() function in SomeTransitRouterFactory. That's also the method used for the custom transit router implemented.

After the MATSim User Meeting that suggested to bind the class directly, I tried

bind(TransitRouter.class).to(SomeTransitRouter.class);

However, turns out that the replanning time was increased by about 75%. The injected constructor has similar logic with the code, but the SomeTransitRouter is created multiple times.

It is even slower for

bind(TransitRouter.class).to(SomeTransitRouter.class).to(Singleton.class);

What is the intuition behind this?

Thank you in advance. The exact codes are attached.

Enoch


Comments: 1


Re: Different way of binding of TransitRouter by class directly

by Thibaut Dubernet on 2018-07-03 10:14:55

Dear Enoch,

this is only an hypothesis, but here is what I think happens:

  • Provider case: the provider is a Singleton, and thus gets initialized once only. It might do some expensive operations at this step. In the default one, I see it creates the transit network router from the schedule and "prepares" the schedule at this stage

  • Bind to class: the logic from the provider had to be moved in the constructor of the transit router. A new instance gets created every time a TransitRouter is requested for injection, so you get this expensive operations done in every iteration, once per thread, once per replanning module using routing. 75% longer computation times sound like a lot for this, but it depends on the size of the scenario and number of threads.

  • Bind to class as singleton: Here only one instance of a transit router is created for the whole VM, instead of one per thread per module. What might happen is that the transit router is implemented in a thread-safe fashion using locks/synchronized blocks (I did not check this hypothesis though). Then, all your replanning threads would compete for the same resources, blocking each other, and slowing the whole thing to a speed similar to a mono-thread run.

Again, those are only hypotheses. I am pretty confident about the two first, less about the third (I do not remember the router being implemented this way). But the bottom line is: this is one of the cases where using providers actually makes sense beyond simple reuse of former factories, so you should keep using this approach.

Clone this wiki locally