Current:
forhinhighway_systems:
print(".",end="",flush=True)
forrinh.route_list:
forsinr.segment_list:
ifs.waypoint1.colocatedisnotNoneands.waypoint2.colocatedisnotNone:
forw1ins.waypoint1.colocated:
ifw1.routeisnotr:
forw2ins.waypoint2.colocated:
ifw1.routeisw2.route:
other=w1.route.find_segment_by_waypoints(w1,w2)
ifotherisnotNone:
ifs.concurrentisNone:
s.concurrent= []
other.concurrent=s.concurrents.concurrent.append(s)
s.concurrent.append(other)
concurrencyfile.write("New concurrency ["+str(s) +"]["+str(other) +"] ("+str(len(s.concurrent)) +")\n")
else:
other.concurrent=s.concurrentifothernotins.concurrent:
s.concurrent.append(other)
#concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(other) + "] ("+ str(len(s.concurrent)) + ")\n")concurrencyfile.write("Extended concurrency ")
forxins.concurrent:
concurrencyfile.write("["+str(x) +"]")
concurrencyfile.write(" ("+str(len(s.concurrent)) +")\n")
print("!")Proposed:
forhinhighway_systems:
print(".",end="",flush=True)
forrinh.route_list:
forsinr.segment_list:
ifs.concurrentisNoneands.waypoint1.colocatedisnotNoneands.waypoint2.colocatedisnotNone:
forw1ins.waypoint1.colocated:
forw2ins.waypoint2.colocated:
ifw1.routeisw2.route:
found=w1.route.find_segment_by_waypoints(w1,w2)
iffoundisnotNone:
ifs.concurrentisNone:
s.concurrent= []
found.concurrent=s.concurrents.concurrent.append(found)
else:
found.concurrent=s.concurrents.concurrent.append(found)
#concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(found) + "] ("+ str(len(s.concurrent)) + ")\n")iflen(s.concurrent) ==2:
concurrencyfile.write("New concurrency ")
else:
concurrencyfile.write("Extended concurrency ")
forxins.concurrent:
concurrencyfile.write("["+str(x) +"]")
concurrencyfile.write(" ("+str(len(s.concurrent)) +")\n")
print("!")if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:->
if s.concurrent is None and s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:
This prevents us from going deeper into the FOR loops and finding concurrencies that are already found. If s.concurrent is not None, it should be fully populated with no need to check further, because:if w1.route is not r: removed: this enables us to find all concurrencies for a given segment on the first pass, including concurrencies on the same route.other renamed to found -- as s itself is now found this way, it's not strictly an "other" any more, is it?s.concurrent.append(s) deleted, as s is now found, and appended that way.if found not in s.concurrent: removed: On the first pass, this is the first time a concurrency will be found, and hence will not be in s.concurrent yet. Future passes are now prevented, making this check unnecessary.- New concurrency logging moved out of the
if s.concurrent is None: case and moved into the else:, because this would log a single-segment concurrency. There's a new IF/ELSE check to determine whether to log "New concurrency " or "Extended concurrency " (shouldn't be a big performance hit :) ), but this was only really done to maintain compatibility with the existing concurrencies.log format, and make DIFFs human-readable while testing this out.
This format, listing each route as it's detected & added to a given segment, certainly made sense when first developing the concurrency detecting code, to make sure things were behaving as expected. Now, with everything pretty stable & behaving as expected for some time now, it may make some sense to trim out some fat and simplify the concurrencies.log file by listing only the final concurrency, with all routes for given segment:
forhinhighway_systems:
print(".",end="",flush=True)
forrinh.route_list:
forsinr.segment_list:
ifs.concurrentisNoneands.waypoint1.colocatedisnotNoneands.waypoint2.colocatedisnotNone:
forw1ins.waypoint1.colocated:
forw2ins.waypoint2.colocated:
ifw1.routeisw2.route:
found=w1.route.find_segment_by_waypoints(w1,w2)
iffoundisnotNone:
ifs.concurrentisNone:
s.concurrent= []
found.concurrent=s.concurrents.concurrent.append(found)
else:
found.concurrent=s.concurrents.concurrent.append(found)
concurrencyfile.write("concurrency ")
forxins.concurrent:
concurrencyfile.write("["+str(x) +"]")
concurrencyfile.write(" ("+str(len(s.concurrent)) +")\n")
print("!")From here, we can see that another possibility is removing the innermost IF/ELSE, and initializing concurrent to an empty list in the HighwaySegment constructor.
I wonder though, whether as opposed to None, this would mean a larger RAM footprint. I'd want to test this out before implementing it.
Between items 2 & 4, we at first see a reduction in efficiency: instead of just doing s.concurrent.append(s), we instead must find_segment_by_waypoints. If we're looking for, say, TX I-10 880 TX/LA, it could take a bit to loop thru the FOR loop in that function. This disadvantage is negated farther down the line, when we no longer need to search for TX US90 I-10(880) TX/LA. Throw a third route or more into the mix, and we have a net savings.
Current:
Proposed:
if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:->if s.concurrent is None and s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:This prevents us from going deeper into the FOR loops and finding concurrencies that are already found. If s.concurrent is not None, it should be fully populated with no need to check further, because:
if w1.route is not r:removed: this enables us to find all concurrencies for a given segment on the first pass, including concurrencies on the same route.otherrenamed tofound-- assitself is now found this way, it's not strictly an "other" any more, is it?s.concurrent.append(s)deleted, assis nowfound, and appended that way.if found not in s.concurrent:removed: On the first pass, this is the first time a concurrency will befound, and hence will not bein s.concurrentyet. Future passes are now prevented, making this check unnecessary.if s.concurrent is None:case and moved into theelse:, because this would log a single-segment concurrency. There's a new IF/ELSE check to determine whether to log "New concurrency " or "Extended concurrency " (shouldn't be a big performance hit :) ), but this was only really done to maintain compatibility with the existing concurrencies.log format, and make DIFFs human-readable while testing this out.This format, listing each route as it's detected & added to a given segment, certainly made sense when first developing the concurrency detecting code, to make sure things were behaving as expected. Now, with everything pretty stable & behaving as expected for some time now, it may make some sense to trim out some fat and simplify the concurrencies.log file by listing only the final concurrency, with all routes for given segment:
From here, we can see that another possibility is removing the innermost IF/ELSE, and initializing
concurrentto an empty list in the HighwaySegment constructor.I wonder though, whether as opposed to
None, this would mean a larger RAM footprint. I'd want to test this out before implementing it.Between items 2 & 4, we at first see a reduction in efficiency: instead of just doing
s.concurrent.append(s), we instead mustfind_segment_by_waypoints. If we're looking for, say,TX I-10 880 TX/LA, it could take a bit to loop thru the FOR loop in that function. This disadvantage is negated farther down the line, when we no longer need to search forTX US90 I-10(880) TX/LA. Throw a third route or more into the mix, and we have a net savings.