if (not doneParsingEvent):
if (batterEvent.startswith('K')):
runnerDests['B'] = 0
runnersDefaultStayStill = True
if (batterEvent.startswith('K+') or batterEvent.startswith('K23+')):
if batterEvent.startswith('K+'):
The "not doneParsingEvent" is used to emulate a "continue" statement. As is, every line can trigger a large number if "if (not doneParsing):" tests.Python's s.startswith() methods are very attractive, but slow compared to the error-prone:
if batterEvent[0] == "K":
...
if batterEvent[:2] == "K+":
..
Here are the timings: % python -m timeit -s 's = "Knights"' 's.startswith("K")'
2000000 loops, best of 5: 119 nsec per loop
% python -m timeit -s 's = "Knights"' 's[:1] == "K"'
5000000 loops, best of 5: 76.5 nsec per loop
% python -m timeit -s 's = "Knights"' 's[0] == "K"'
5000000 loops, best of 5: 41.4 nsec per loop
There are a number of uses of: simpleHitMatch = getRe(r"^([SDTH])(?:\d|/)").match(batterEvent)
where "getRe()" implements a simple regex cache. However 1) re.match() also implements a simple regex cache, and 2) I typically implement this as a per-module variable, one per regex: _simple_hit_pattern_matcher = re.compile(r"^([SDTH])(?:\d|/)").match
which is then used as: simpleHitMatch = _simple_hit_pattern_matcher(batterEvent)
This would reduce the call overhead by removing the double cache table lookup.Bear in mind that I don't know where the time is spent (so I may be looking in the wrong place) and I don't think these changes could get an 8x performance improvement.