Optimizations of frequently called checks

Started by Adil, January 27, 2018, 07:29:25 AM

Previous topic - Next topic

Adil

I've been playing around with buttons recently. I've added the following harmony patch to the game:
           
static class Building_Bed_GetGizmos_Patch
{
  static void Postfix(ref IEnumerable<Gizmo> __result, ref Building_Bed __instance)
  {
      Log.Message("Prisoner bed patch run ")
  ...
  }
}

This code is run every time after the vanilla GetGizmos is performed on a building.
With the code above, one gets a single log message on every tick even if nothing happens to the building (even on pause).

Is it presence of Log.Message() that forces function rerun, or is it vanilla behavior to rerun all the checks regardless of absence of change?

The code in question was quite short and checks were simple, so not much time is lost there, probably.  Not in this particular case but, say, in PawnCapacityWorker (or JobGiver or Comp) routines some more complex calculations may be desired, and those seem to get called often too.
What would be optimization tricks for those?

crusader2010

You should ask the author of Harmony, but, as I understand it, every time a method like GetGizmo gets called, that has a post-execution harmony patch attached, this patch will always get called. And, most likely, that method gets called for every object (on the map?), or as you move the viewpoint.

Sorry for not really being of much help :) just barely started with Rimworld C# modding.
My mod pack: {A13} Mod Mega Pack

Adil

The harmony is not the point of the question. Yes, a function attached by harmony is called every time after the function that it is attached to. That's the entire point of a patch.

Here, I've used harmony patch to indicate that the core game function GetGizmos is called multiple times per second for the same object without any actual need to.

I'm not quite familiar with c# but I do know some languages' compilers can detect redundant calls and optimize them away. And in some cases input\output operations are treated as a reason not to optimize the encompassing fucntion in such way.

So the question 1 was: Did I break rimworld optimizations by injecting the i/o-operations or is it always needlessly regenerating all the objects each frame?

The question 2 is: How would one optimize these calls so that they do not do much work when nothing changes? I do know people tend to just set functions to be called on certain ticks only, but is there any common way to do caching for example?