This tutorial is going to be on caching, caching is a great and easy way to improve performance.
First of all, what is a cache and/or caching? In few words, it's just storing a result or a variable in another variable to use later.
It's possible you already do this and didn't know what it was since it's something pretty easy and common to do.
You usually want to cache something when you either need to use a function several times and you know the result won't change or because you are going to update a variable but want to access it's previous value later. You might also want to cache a result of a function to compare it later to see if the result changed.
For example:
var
RSW: TRSWalker;
TickCountCache: UInt64;
begin
RSW.Setup('world'); //I choose world map on purpose because it's super slow!
while True do
begin
TickCountCache := GetTickCount;
WriteLn('Position: ', RSW.GetMyPos);
WriteLn('This took ', GetTickCount - TickCountCache, 'ms to compute');
end;
end;
In this example we cache GetTickCount
in TickCountCache
to calculate how long we took to perform WriteLn('Position: ', RSW.GetMyPos);
Now let's say we want to improve the performance of our script.
This is a extremely simple script it only gets your position and prints it.
This example is not even useful in a real script scenario but anyway, because RSW.GetMyPos
is actually quite slow, specially in the full 'world' map and because we know we will not move while the script is running, RSW.GetMyPos
will always return the same coordinates so we can improve the performance dramatically by checking RSW.GetMyPos
once and caching it's result, then we print the cache!
We can do so like this:
var
RSW: TRSWalker;
Position: TPoint;
TickCountCache: UInt64;
begin
RSW.Setup('world');
Position := RSW.GetMyPos;
while True do
begin
TickCountCache := GetTickCount;
WriteLn('Position: ', Position);
WriteLn('This took ', GetTickCount - TickCountCache, 'ms to compute');
end;
end;
You see now that this will be blazing fast compared to the previous example. However like I said before, this example only works properly the result doesn't change throughout the script executive.
If you were to move while the script is moving not be printing you actual position anymore while the first script would still work, so keep that in mind.
That's about everything I can teach you about caches they can be very useful when you are creative with them.
If you want to check some examples have a look at TBaseBankScript.BankTab
which I use to cache a script bank tab or SRL's TRSMM2MS.ZoomLevel
which is used to cache you zoom level.
Lastly we can use it to figure out if RSW.GetMyPos
changed.
var
RSW: TRSWalker;
Position: TPoint;
begin
RSW.Setup('world');
Position := RSW.GetMyPos;
while True do
begin
if Position = RSW.GetMyPos then
WriteLn('Position didn''t change')
else
begin
Position := RSW.GetMyPos;
WriteLn('New position: ', Position);
end;
end;
end;
Now we are using the cache to compare it to a previous result, if the new result is different we update it.
But if you notice, when we get a new result we are actually RSW.GetMyPos
twice in that loop, we could also improve the performance of that by caching it as well!
For example:
var
RSW: TRSWalker;
PrevPos, NewPos: TPoint;
begin
RSW.Setup('world');
PrevPos := RSW.GetMyPos;
while True do
begin
NewPos := RSW.GetMyPos;
if PrevPos = NewPos then
WriteLn('Position didn''t change')
else
begin
PrevPos := NewPos;
WriteLn('New position: ', NewPos);
end;
end;
end;
Now we will only ever call RSW.GetMyPos
once per loop, which gives us the best performance possible for this particular script.
I hope you found this quick tutorial useful!