Hi, I’ve noticed that my some of my scripts have a linearly increasing rate but constant activity (seen under script performance). I’ve tried to look for more specific information on what rate and activity entails, but all I could really find was that activity is the percent of CPU power that the script (and its duplicates) are using, and rate is how often the script is executed over the total time.
So the conclusion I made was that my scripts are executed more and more as time goes on, while the total CPU usage of the scripts remain constant.
What exactly does this mean in terms of performance? I would believe that increasing rate is definitely not good, but activity still remains fairly low, and show no growth. In addition, I did not notice increase in memory either, so I’m fairly puzzled about the exact implication of increased rate but constant activity for scripts. Thanks for the help!
Activity is what affects performance necessarily, while rate does not. When optimizing, look primarily for activity, as you can have scripts that run very frequently (high rate) but don’t do very intensive tasks, thus having low activity and low performance impact.
For example, the following code will exhibit a high rate (30/s), but low activity:
while true do
wait()
print("0")
end
My concern is that the rate increases linearly, and while activity is certainly low, I can’t imagine rates on the order of ~100000/s being any good. What puzzles me is that, yes, some loop would definitely increase rate, but a continuous increase in rate implies that the script creates more loops (which, I would expect, would still increase activity). But here, the activity does not increase, but rate continues to increase.
For a concrete example of the issue, here is a standalone LocalScript that demonstrates a script that shows constant activity but linearly increasing rate (a freemodel first person camera manipulation script):
repeat wait() until game:GetService("Players").LocalPlayer.Character ~= nil
local runService = game:GetService("RunService")
local input = game:GetService("UserInputService")
local players = game:GetService("Players")
CanToggleMouse = {allowed = true; activationkey = Enum.KeyCode.F;}
CanViewBody = false
Sensitivity = 0.6
Smoothness = 0.05
FieldOfView = 90
local cam = game.Workspace.CurrentCamera
local player = players.LocalPlayer
local m = player:GetMouse()
m.Icon = "http://www.roblox.com/asset/?id=569021388" -- replaces mouse icon
local character = player.Character or player.CharacterAdded:wait()
local humanoidpart = character.HumanoidRootPart
local head = character:WaitForChild("Head")
local CamPos,TargetCamPos = cam.CoordinateFrame.p,cam.CoordinateFrame.p
local AngleX,TargetAngleX = 0,0
local AngleY,TargetAngleY = 0,0
local running = true
local freemouse = false
function updatechar()
for _, v in pairs(character:GetChildren())do
if CanViewBody then
if v.Name == 'Head' then
v.LocalTransparencyModifier = 1
v.CanCollide = false
end
else
if v:IsA'Part' or v:IsA'UnionOperation' or v:IsA'MeshPart' then
v.LocalTransparencyModifier = 1
v.CanCollide = false
end
end
if v:IsA'Accessory' then
v:FindFirstChild('Handle').LocalTransparencyModifier = 1
v:FindFirstChild('Handle').CanCollide = false
end
if v:IsA'Hat' then
v:FindFirstChild('Handle').LocalTransparencyModifier = 1
v:FindFirstChild('Handle').CanCollide = false
end
end
end
input.InputChanged:connect(function(inputObject)
if inputObject.UserInputType == Enum.UserInputType.MouseMovement then
local delta = Vector2.new(inputObject.Delta.x/Sensitivity,inputObject.Delta.y/Sensitivity) * Smoothness
local X = TargetAngleX - delta.y
TargetAngleX = (X >= 80 and 80) or (X <= -80 and -80) or X
TargetAngleY = (TargetAngleY - delta.x) %360
end
end)
input.InputBegan:connect(function(inputObject)
if inputObject.UserInputType == Enum.UserInputType.Keyboard then
if inputObject.KeyCode == CanToggleMouse.activationkey then
if CanToggleMouse.allowed and freemouse == false then
freemouse = true
else
freemouse = false
end
end
end
end)
runService.RenderStepped:connect(function()
if running then
updatechar()
CamPos = CamPos + (TargetCamPos - CamPos) *0.28
AngleX = AngleX + (TargetAngleX - AngleX) *0.35
local dist = TargetAngleY - AngleY
dist = math.abs(dist) > 180 and dist - (dist / math.abs(dist)) * 360 or dist
AngleY = (AngleY + dist *0.35) %360
cam.CameraType = Enum.CameraType.Scriptable
cam.CoordinateFrame = CFrame.new(head.Position)
* CFrame.Angles(0,math.rad(AngleY),0)
* CFrame.Angles(math.rad(AngleX),0,0)
* CFrame.new(0,0.5,0) -- offset
humanoidpart.CFrame=CFrame.new(humanoidpart.Position)*CFrame.Angles(0,math.rad(AngleY),0)
else game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.Default
end
if (cam.Focus.p-cam.CoordinateFrame.p).magnitude < 1 then
running = false
else
running = true
if freemouse == true then
game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.Default
else
game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.LockCenter
end
end
if not CanToggleMouse.allowed then
freemouse = false
end
cam.FieldOfView = FieldOfView
end)
A cursory examination of this code shows that, there are no loops or function calls that linearly increase the number of loop/function calls (i.e. loops don’t spawn more loops, which spawn more loops, so on and so forth). I’m more puzzled now if the rate statistic in Script Performance is not behaving as desired, or if there are some internal engine/studio source code that is affecting the perceived discrepancies between activity and rate.
I’m unable to replicate the behavior you described with the example you provided. The rate stays at 30/s as expected.
It seems like this is a bug. I develop on a Mac, so after your reply I ran the sample code on a Windows machine, and realized the rate shows 30/s, as opposed to a linearly increasing amount seen from my Mac. Thanks for attempting to replicate the behavior.
Resolution: It seems that Studio on Mac shows incorrect rate for scripts on Script Performance. I will submit a bug report on this later. But it seems increasing rate but constant activity is an abnormal behavior.