Skip to content

LUA Blueprint and Category lookup speeds

IceDreamer edited this page Jul 9, 2017 · 5 revisions
TestThread = function(self)
    WARN("Test thread activated")

    local t = GetSystemTimeSecondsOnlyForProfileUse()
    for i = 1, 10000 do
        local cat = EntityCategoryContains(categories.AIR, self)
    end
    t = GetSystemTimeSecondsOnlyForProfileUse() - t
    WARN("Test 1 complete, time elapsed for EntityCategoryContains is " .. t)
    
    t = GetSystemTimeSecondsOnlyForProfileUse()
    for i = 1, 10000 do
        local bp = self:GetBlueprint()
        local cat = bp.CategoriesHash.AIR
    end
    t = GetSystemTimeSecondsOnlyForProfileUse() - t
    WARN("Test 2 complete, time elapsed for self:GetBlueprint followed by bp.CategoriesHash.AIR is " .. t)
    
    t = GetSystemTimeSecondsOnlyForProfileUse()
    for i = 1, 10000 do
        local bp = GetBlueprint(self)
        local cat = bp.CategoriesHash.AIR
    end
    t = GetSystemTimeSecondsOnlyForProfileUse() - t
    WARN("Test 3 complete, time elapsed for globally localised GetBlueprint(self) followed by bp.CategoriesHash.AIR is " .. t)
    
    t = GetSystemTimeSecondsOnlyForProfileUse()
    for i = 1, 10000 do
        local cat = BluePrints[self.UnitId].CategoriesHash.AIR
    end
    t = GetSystemTimeSecondsOnlyForProfileUse() - t
    WARN("Test 4 complete, time elapsed for globally localised __blueprints table lookup of BluePrints = __blueprints.Unit -> BluePrints[self.UnitId].CategoriesHash.AIR is " .. t)
    
    t = GetSystemTimeSecondsOnlyForProfileUse()
    for i = 1, 10000 do
        local cat = __blueprints.Unit[self.UnitId].CategoriesHash.AIR
    end
    t = GetSystemTimeSecondsOnlyForProfileUse() - t
    WARN("Test 5 complete, time elapsed for __blueprints.Unit[self.UnitId].CategoriesHash.AIR is " .. t)
    
    t = GetSystemTimeSecondsOnlyForProfileUse()
    for i = 1, 10000 do
        local cat = _G.__blueprints.Unit[self.UnitId].CategoriesHash.AIR
    end
    t = GetSystemTimeSecondsOnlyForProfileUse() - t
    WARN("Test 6 complete, time elapsed for _G.__blueprints.Unit[self.UnitId].CategoriesHash.AIR is " .. t)
    
    local bp = GetBlueprint(self)
    t = GetSystemTimeSecondsOnlyForProfileUse()
    for i = 1, 10000 do
        local cat = bp.CategoriesHash.AIR
    end
    t = GetSystemTimeSecondsOnlyForProfileUse() - t
    WARN("Test 7 complete, time elapsed for cases where local bp = GetBlueprint(self) has been done for other reasons already, followed by bp.CategoriesHash.AIR is " .. t)
end,

This code resulted the following:

WARNING: Test thread activated
WARNING: Test 1 complete, time elapsed for EntityCategoryContains is 0.00274658203125
WARNING: Test 2 complete, time elapsed for self:GetBlueprint followed by bp.CategoriesHash.AIR is 0.00299072265625
WARNING: Test 3 complete, time elapsed for globally localised GetBlueprint(self) followed by bp.CategoriesHash.AIR is 0.00274658203125
WARNING: Test 4 complete, time elapsed for globally localised __blueprints table lookup of BluePrints = __blueprints.Unit -> BluePrints[self.UnitId].CategoriesHash.AIR is 0.00079345703125
WARNING: Test 5 complete, time elapsed for __blueprints.Unit[self.UnitId].CategoriesHash.AIR is 0.00103759765625
WARNING: Test 6 complete, time elapsed for _G.__blueprints.Unit[self.UnitId].CategoriesHash.AIR is 0.00115966796875
WARNING: Test 7 complete, time elapsed for cases where local bp = GetBlueprint(self) has been done for other reasons already, followed by bp.CategoriesHash.AIR is 0.000244140625

From this we can see several things.

Calling self:GetBlueprint() is slightly slower than using a local GetBlueprint(self) defined as local GetBlueprint = moho.entity_methods.GetBlueprint at top of file.

Where bp has already been fetched, it is much faster to simply grab the value from bp.CategoriesHash[cat] than to use EntityCategoryContains

Where it hasn't. the hash lookup + a new function call to get the blueprint is slower than just using EntityCategoryContains

All methods of getting a blueprint directly from the Global table are faster than either of the functions, but using local bps = __blueprints.Unit at top of file results in the fastest of these (It skips checking _G and __blueprints and jumps right in)

Conclusion:

  • All unit blueprint lookups should be changed from using functions to using bps[self.UnitId], with UnitId stored in OnCreate. Further investigation of function vs lookup below.
  • Where a single category is being looked up, use the CategoriesHash blueprint entry

Clone this wiki locally