The bulk of that time taken up in the method with the signature:
Given the CounterGroup/Counters are pretty simple and from what I can figure out through crude profiling is that the outer loop gets called some 4.5 million times and the inner loop nets out around 37 million times. Even as fast as it may be, the sheer number of counters adds up over so many tasks.
The only solution I can see offhand would be to defer this conversion to when the user clicks on the Counters link in the Tasks page. This would mean substituting the calls like:
in CompletedTaskAttempt (and similar places if any) and adjusting the JHS method that accesses the counters to do the parsing at link click time.