Questions about how time is calculated

Hi, I’ve been here awhile. I’ve searched the forum for answers to these questions but not found anything that really answers them.

I have a couple questions about how timeout is calculated and what I can do to monitor the time spent in my program. I’m currently coding in c# and using StopWatch. I determined that the Codingame is using the high resolution timer which is great, but in the puzzle I’m currently working on (CodeRoyale) the time per-turn is 50 milliseconds, and I’m timing my code and it exceeds 50 milliseconds regularly, but I’m not getting a timeout. This is before I’m even doing any significant code logic, and all I’m doing is parsing the input, I’m not calculating any derived values from the input. I suspect that Console.Readline is taking most of the time since IO is very slow.

Which leads me to my first question: Does IO time count? Could I possibly get a more accurate time measurement in my code if I stop the stopwatch before Console.Readline and restart it afterwards? Because according to my calculations, I should be timing out already before I’ve even really started coding my solution to the problem, so that’s discouraging me from going any further.

And the other question is, are there docs anywhere that explain how CG calculates time spent in my code? Or can any members chime in with their experience and opinion about this?

Hey.
To get a measure of time as accurate as possible, you have to start your timer after the first input, and to stop it before your output. Otherwise you will also measure the referee’s time, and the one of your opponent(s).

1 Like

Thanks, I started the timer after the first Console Readline and now I get sensible numbers!

Just imagine how would you write the timer if you were working in CG.
You can’t start measuring computation time after sending some input because you are risking, that user’s code will do some heavy computation before processing the input so CG starts timer right before sending you first input. Since you don’t know exactly when CG will send you first input, best place to start your own timer is right after first input is received (you will be a few nanoseconds off but it shouldn’t be significant)

After you reach timer you have to shut down computations immediately. The shut down can be “costly” too for example if you are computing some tree and you hit the timer in 10th layer that has still 10.000 nodes to compute, you will most probably time out too

Thanks for the reply! Yeah I plan to have a healthy cushion for my kill switch, probably 3-5 milliseconds to avoid any timeout issues. I’m actually surprised how much I can do in 50 milliseconds, I thought it would be a difficult limit but it’s actually probably extreme overkill for what I have planned so far. I imagine when I get to higher levels it will start to become more of an obstacle.

I also still have timing woes (C#). I was most recently optimizing SameGame, so I’ll use that as an example. The initial turn is 20 seconds. Starting my stopwatch after input and letting my algorithm run for 19.5 seconds works great. If I start before the input, I lose about 2.5 seconds for whatever initialization reasons (that is, if I keep my internal timeout at 19.5 seconds, CodinGame will complain that I timed out).

Next is a 50 ms per turn cycle. I can get the IDE to allow 70 ms per turn. Currently my Stopwatch.Restart() is put right after reading the input, but there’s no difference if I move it to before as suggested above. However, if I submit this code, which passes IDE tests, I get numerous timeouts on the leaderboard. I currently have my timeout set to 35 ms in order to pass consistently :frowning:. Maybe this 15 ms difference will be solved by moving Stopwatch.Restart(), despite it not showing any difference in the IDE. In conclusion, you can’t optimize your timeouts in CodinGame’s IDE.

On a similar note, in the Spring 2021 challenge, one of my solutions could challenge itself successfully in the IDE. However, it would timeout when I submitted it to the leaderboard, but only if it was Player #2 :confused: