Elvas Tower: Trains slow to load - Elvas Tower

Jump to content

  • 2 Pages +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

Trains slow to load Rate Topic: -----

#1 User is offline   systema 

  • Fireman
  • Group: Status: Active Member
  • Posts: 107
  • Joined: 16-March 15
  • Gender:Male
  • Location:The Heart of Cheshire
  • Simulator:Open Rails
  • Country:

Posted 20 October 2021 - 01:17 PM

I only have 9 trains in my timetable.

The first 7 load at a good speed. After adding two more trains the last two are very slow to load (I have #path /binary set up). The first 7 are still quick to load.

Would there be a particular reason for this, or is it normal. I cant imagine how slow it would be if I had say 50 plus trains.

Mick Clarke
MEC

#2 User is offline   Weter 

  • Member, Board of Directors
  • PipPipPipPipPipPipPipPipPipPip
  • Group: ET Admin
  • Posts: 6,806
  • Joined: 01-June 20
  • Gender:Not Telling
  • Simulator:ORTS
  • Country:

Posted 20 October 2021 - 01:41 PM

I think, it depends on time (pre-run)
E.g. As I have first train at 4A.M. And last at 23:56P.M. Loading takes about 10-12 minutes.
Step is 1-5sec of game time during that pre-run.

Can't see any benefit from /binary...
But can you see: did binary variants at least appeared in respective subfolder of your route?

#3 User is offline   systema 

  • Fireman
  • Group: Status: Active Member
  • Posts: 107
  • Joined: 16-March 15
  • Gender:Male
  • Location:The Heart of Cheshire
  • Simulator:Open Rails
  • Country:

Posted 20 October 2021 - 03:35 PM

Yes the binary variants are there.

Mick Clarke
MEC

#4 User is offline   roeter 

  • Vice President
  • Group: Status: Elite Member
  • Posts: 2,420
  • Joined: 25-October 11
  • Gender:Male
  • Country:

Posted 22 October 2021 - 12:44 AM

Load time for timetables depends on the starttime of the selected train. The time taken by the prerun processing to get to the required starttime depends on the required time, the no. of trains to be run and the size of the route, in particular the number of signals on the route. Signal processing takes up a fair portion of the required processing time during prerun.
If the two trains which were added have starttimes near the end of the day, you will see much longer load times.

The $binary for the path will start making a difference when you get to 100's of paths. It will make a very significant difference when the total number of paths reaches the 1000's.

Regards,
Rob Roeterdink

#5 User is offline   Weter 

  • Member, Board of Directors
  • PipPipPipPipPipPipPipPipPipPip
  • Group: ET Admin
  • Posts: 6,806
  • Joined: 01-June 20
  • Gender:Not Telling
  • Simulator:ORTS
  • Country:

Posted 22 October 2021 - 11:40 PM

Quote

The $binary for the path will start making a difference when you get to 100's of paths. It will make a very significant difference when the total number of paths reaches the 1000's.

Thank you, Robert: I owe to include this note to my translated version of 11-th chapter. Be well!

#6 User is offline   gpz 

  • Superintendant
  • Group: Status: Elite Member
  • Posts: 1,771
  • Joined: 27-October 12
  • Gender:Male
  • Location:Budapest
  • Simulator:OpenRails
  • Country:

Posted 22 November 2021 - 02:22 AM

Rob,

I just came to the issue of long loading times of big timetables, and started to browse the code just if something trivial hits my eyes as a possbile optimization, and without actually trying to do any changes, I couldn't go past something odd to me at loading the paths. I thought it is worth a question, because there might be some obvious reason of it I am overlooking.

The TimetableInfo.LoadPath() method has a return AIPath outPath value, and at the same time it also produces the paths as Paths.Add(....). But the method does this by creating a new AIPath(...) for both! So it always creates:

outPath = new AIPath(...);
Paths.Add(formedpathFilefull, new AIPath(outPath));


So if the path is loaded from either the ascii or the binary format, 2 new AIPath() instances are getting created. The only difference is that when the path is found in the Paths dictionary, then only 1 additional new AIPath() is created for the return outPath value. Why isn't just a single object is created, so the same one is added to the Paths dictionary and also returned? Are these AIPath objects modified somewhere later in the code, or some thread safety issue appears there?


Moreover, looking at the TimetableInfo.PreProcessRoutes() method, I see, that the path is loaded in the following line:

AIPath newPath = LoadPath(thisRoute, out pathValid);


But later the newPath variable is not used for anything, is dropped. So actually the AIPath object, that is created as a return value in the LoadPath() method is dropped, so it is created in vain in pre-process. I think this might affect the loading time in case of many paths. What do you think?

#7 User is offline   roeter 

  • Vice President
  • Group: Status: Elite Member
  • Posts: 2,420
  • Joined: 25-October 11
  • Gender:Male
  • Country:

Posted 23 November 2021 - 01:28 AM

Well, my first thoughts on this were that it is a pretty long time ago since I created that code. I needed a thorough check of the code to get some idea of what was done at the time.
First, about the variable NewPath. The issue here is that the method LoadPath() is used at a number of different locations. It has an output variable defined, which is the created path. In some locations where this method is called, this path is indeed actively used (e.g. stable, runround commands, and in pools). In some, in particular when loading new paths, it is not used. But it's a bit much to set up two methods for this same processing - one with, and one without output variable. So that's why a dummy variable is used in the PreProcessRoute method. It could be deleted, but that wouldn't help much as the LoadPath will still always create the output variable.

As for coyping the path to the two different outputs (list and output variable) - yes, that is necessary. If you store the created path in the list and use that same instance as output variable, any changes made to either will also affect the other as there is only a single instance of that path. I have had other instances with other objects where I have had such problems.

I do not think these two issues have any significant impact on loading time. That is shown if you use binary paths in timetables - loading binary paths is very quick indeed. Loading non-binary paths takes a lot of time as the conversion is a two-step process. First, the path information as stored is converted to tdb-node information, and then this information is converted to a track-circuit list. The reason for this two-step conversion is that when track-circuits were introduced, the original path conversion allready existed. It was deemed too complicated to rewrite so as to create a track-circuit list directly. So, instead, that conversion was left unaltered and the additional conversion was added. It might save processing time if a single step conversion was created, but that's no mean task.

Regards,
Rob Roeterdink

#8 User is offline   gpz 

  • Superintendant
  • Group: Status: Elite Member
  • Posts: 1,771
  • Joined: 27-October 12
  • Gender:Male
  • Location:Budapest
  • Simulator:OpenRails
  • Country:

Posted 23 November 2021 - 02:38 AM

Probably you are right, it is not the major factor of the loading time, because "doubleing" the object is probably done in a comparable time as loading the binary version. So eliminating it at best would halven the binary-loading time, and reduce the ascii-loading time only by a half-binary-loding-time. But still, the imperfection bugs me :-) (I know, there are a lot more imperfections, but I don't know about them), and the question is in my head:

Does an AIPath object ever gets modified, once it is created?

I would think, no. After all, a path is just a predefined path, I doubt it ever gets modified. I admit, copying an object before use is a good practice to avoid mainly the thread safety issues, but only for objects modified. For readonly ones it is not necessary. Do you remember any places in the code where such a path is modified?

And there is this: Better management of binary paths for timetables
Because of this blueprint, the LoadPath() method is to be rewritten, so I think it would be reassuring for the to-be implementer, if you could confirm, that the object-copying could be safely removed from there. (The blueprint requires a small change only, I might do it, if I get into mood, not to get out of practice...)

EDIT: I've made a minimal-modification branch of the original code with retaining the object cloning everywhere but the pre-processing phase (no blueprint implementation): No train path cloning at route pre-precess phase

#9 User is offline   Laci1959 

  • Foreman Of Engines
  • Group: Status: Contributing Member
  • Posts: 910
  • Joined: 01-March 15
  • Gender:Male
  • Simulator:Alföld
  • Country:

Posted 23 November 2021 - 04:01 AM

Quote

I would think, no. After all, a path is just a predefined path, I doubt it ever gets modified. I admit, copying an object before use is a good practice to avoid mainly the thread safety issues, but only for objects modified. For readonly ones it is not necessary. Do you remember any places in the code where such a path is modified?


Hello.

Unfortunately, this is not always the case. I have repeatedly noticed that the OR has deviated from the described route and led me in a direction I did not want. I made a short route for the TT observer and the program extended it beyond the End point and also set a switch in a diverted direction to protect the crawling AI train.
Also in Activity mode, you have extended the path of the incoming AI beyond the End point declared in the path. He set a switch and a signal for himself, thus stopping the train he was driving. As it did not go on, it resulted in an unresolved situation.

Sincerely, Laci 1959

Sorry, Google translates if you have difficulty understanding.

#10 User is offline   roeter 

  • Vice President
  • Group: Status: Elite Member
  • Posts: 2,420
  • Joined: 25-October 11
  • Gender:Male
  • Country:

Posted 23 November 2021 - 04:22 AM

 gpz, on 23 November 2021 - 02:38 AM, said:

Probably you are right, it is not the major factor of the loading time, because "doubleing" the object is probably done in a comparable time as loading the binary version. So eliminating it at best would halven the binary-loading time, and reduce the ascii-loading time only by a half-binary-loding-time. But still, the imperfection bugs me :-) (I know, there are a lot more imperfections, but I don't know about them), and the question is in my head:

Does an AIPath object ever gets modified, once it is created?

I would think, no. After all, a path is just a predefined path, I doubt it ever gets modified. I admit, copying an object before use is a good practice to avoid mainly the thread safety issues, but only for objects modified. For readonly ones it is not necessary. Do you remember any places in the code where such a path is modified?

No, I guess the AIPath is indeed never changed. It is (almost) immediately converted to the TCRoutePath (which is the track-circuit based path), and that's the path which is used in the actual running of trains. After conversion, AIPath is never used again.
But I don't think this copy action is responsible for half the binary loading time. Don't forget you have the actual read file action, which of course requires disk access, and that will probably be the most time-consuming part of the read process.

Quote

And there is this: Better management of binary paths for timetables
Because of this blueprint, the LoadPath() method is to be rewritten, so I think it would be reassuring for the to-be implementer, if you could confirm, that the object-copying could be safely removed from there. (The blueprint requires a small change only, I might do it, if I get into mood, not to get out of practice...)

Yes, I agree with that. I did once alter the code of the trackviewer, such that if you saved a path, it checked if there was a binary version of this path and then deleted it. But somehow, this change never made it into the official code, and after several updates it's now lost.

Quote

EDIT: I've made a minimal-modification branch of the original code with retaining the object cloning everywhere but the pre-processing phase (no blueprint implementation): No train path cloning at route pre-precess phase

Well, if it works I see no problem with that.

 Laci1959, on 23 November 2021 - 04:01 AM, said:

Hello.

Unfortunately, this is not always the case. I have repeatedly noticed that the OR has deviated from the described route and led me in a direction I did not want. I made a short route for the TT observer and the program extended it beyond the End point and also set a switch in a diverted direction to protect the crawling AI train.
Also in Activity mode, you have extended the path of the incoming AI beyond the End point declared in the path. He set a switch and a signal for himself, thus stopping the train he was driving. As it did not go on, it resulted in an unresolved situation.

Sincerely, Laci 1959

The path which is used in the actual train running is the TCRoutePath, based on track-circuits. It's not the AIPath, which is the 'intermediate' path version based on tdb nodes. As I said above, the path processing is a two-step conversion, and the AIPath is the result of the first step, and only used as input for the second step. AIPath is not even stored in the train data.

Regards,
Rob Roeterdink

  • 2 Pages +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users