swarm-game / swarm

Resource gathering + programming game
Other
835 stars 52 forks source link

Optimize WindowedCounter insertion #1558

Open xsebek opened 11 months ago

xsebek commented 11 months ago

I originally thought this was caused by inserting robots in tick, but that function seems to be OK.


The performance analysis in #1557 showed that 5% of time will be spent inserting to WindowedCounter

Inspecting profile with Profiteur
Screenshot 2023-09-30 at 14 47 50

The percentage of time is likely proportional to number of robots running a lot of computations. So optimising the program does not make this performance issue go away, it will only show up again in other scenarios with a lot of robots.

Proposed solution

Consider avoiding this when not necessary.

E.g. turn it off for system robots unless a new --debug=+count-all option is specified.

xsebek commented 11 months ago

Actually, I just noticed this is about a different new insert for WindowedCounter! So robot are not the issue. 😄

@kostmo any idea why insert is taking so much time? (It goes down to 1% after scenario optimisations though.)

byorgey commented 11 months ago

The WindowedCounter is used to keep track of ticks on which a robot actually did something, so we can show statistics about the robot's "load" (i.e. percentage of ticks on which it is active) in the F2 dialog.

What if we only update WindowedCounter when the F2 dialog is actually open? The downside is that it would take the activity values a little bit of time to "warm up" and stabilize after opening the dialog instead of just having the values immediately available, but it should save a lot of time in the common case that we are not computing activity percentages.

I also wonder whether using an IntSet instead of a generic Set in WindowedCounter would help with performance.

kostmo commented 11 months ago

I also wonder whether using an IntSet instead of a generic Set in WindowedCounter would help with performance.

I think then that the underlying type of TickNumber would have to become Int rather than Integer. I actually experimented with that randomly in #1491. Any reason it would need to remain as Integer?

xsebek commented 11 months ago

@kostmo as long as it is 64 bit it should be enough to store time, I am not sure what the situation is on Windows.

byorgey commented 11 months ago

Hmm, agreed, with a 32-bit signed Int it is just conceivable for someone to keep the game running long enough for the tick number to overflow. E.g. if someone has the game set to 1024 ticks per second, then 2^21 seconds is only about 24 days. On the other hand, with a 64-bit Int, at 1024 t/s you could run the game for almost 300 million years before overflow.

I always assume these days that Int is always 64 bits but I am not sure how valid that assumption is.

xsebek commented 11 months ago

@byorgey very recently I learned to not trust that assumption on Windows with C# after some timer was set to over two weeks in miliseconds. 😄

byorgey commented 11 months ago

I learned to not trust that assumption on Windows with C# after some timer was set to over two weeks in miliseconds. 😄

Hah! Yes, the time it bit me was when I was doing a programming contest using Haskell and it turned out the server running my submitted code had 32-bit Ints which made my solution fail.