GenericCache:
Information:
GenericCache is an instance-caching ModuleScript that allows for the creation and management of multiple caching objects. The module is designed to be highly customizable and fast, making it a great choice in various situations.
Instance-caching is a technique for efficiently reusing objects. Rather than repeatedly creating and destroying objects with .new()
and :Destroy()
, GenericCache stores unused objects in a table for future use. While instance-caching is always beneficial for maintaining game performance, its advantages become particularly noticeable when dealing with hundreds or thousands of operations per second. The reduction of overhead associated with the frequent creation and destruction of objects makes GenericCache useful in a wide range of scenarios ranging from particle management to gun systems.
Features:
Create GenericCache Objects:
- Store custom types or Instances
- Pass arguments to constructors or use a template instance
- Preload an initial number of objects into the cache
- Set a size limit for the cache
- Automatically run a reset method on any objects added to the cache
Update GenericCache Instance Data:
- Dynamically change the maximum size of the cache
- Change whether the reset method is called on objects added
- Modify the reset method called on objects that are added
Check the Contents of GenericCache Objects:
- View the size of the cache
- View the object that will be returned next
- Use a predicate function to check if the cache contains a specific object
Add, Remove, Return, and Retrieve objects to and from GenericCache objects:
- Manually insert sets of objects or load them in bulk
- Return or retrieve the next object or objects that match a predicate function
- Remove specific objects from the cache.
Clear, Reset, and Destroy GenericCache Objects:
- Clear the contents of the cache for garbage collection
- Reset the cache to its default state
- Destroy the cache, including its metatable and contents
Performance:
GenericCache is highly optimized and boasts fast runtimes across the board. The table below provides the performance metrics for most of the ModuleScript’s methods, categorized by the use of custom types or Instances. Differences between the two stem from the additional overhead associated with Instances compared to more lightweight, script-based types.
Runtime Table
All runtimes for the table represent the average execution time over 1000 test runs following an initial warm-up of 100 test runs to take advantage of JIT compilation. For methods with varying outputs based on their input arguments, testing was performed using more basic objects unless otherwise specified. Brackets in the arguments column signify different sets of arguments and ranges in the runtime column signify the difference in runtimes between caches storing custom types and those storing Instances.
-- Example GenericCache Objects
local testClass = require(testClass)
GenericCache.new(testClass, {}) – custom type cache
GenericCache.new(Instance, {"IntValue"}) – Instance cache
Function / Method | Arguments | Average runtime (s) |
---|---|---|
.new() | TestObject, {} | 1.5E-7 |
:SetMaxSize() | 10 | 5E-8 |
:SetResetOnAddition() |
true , true
|
2E-7 |
:SetResetMethodName() | “Reset”, true
|
2E-7 |
:ContainsObject() | TestObject.new() | 1E-7 |
:LoadObjects() | 10 | 7.5E-7 - 7E-6 |
:AddObject() | TestObject.new() | 1E-7 - 2E-7 |
:AddObjects() | 10 | 3E-7 - 8.5E-7 |
:ReturnObject() | 5E-8 | |
:ReturnCustomObject() | function(object) return true end | 8.5E-8 |
:ReturnCustomObjects() | function(object) return true end | 6.5E-7 |
:RemoveObject() | TestObject.new() | 1.5E-7 |
:RetrieveObject() | 6E-8 | |
:RetrieveCustomObject() | function(object) return true end | 1E-7 |
:RetrieveCustomObjects() | function(object) return true end | 6.5E-7 |
:ClearCache() | 6E-8 - 8E-8 | |
:Reset() | 7E-8 - 9E-8 | |
:Destroy() | 1E-7 |
Usage:
Creating Caches
Creating a GenericCache Object:
The first step to using GenericCache is requiring the module and instantiating anything that will be used in the constructor. In this case, that includes a template Instance.
-- GenericCache should be stored in RPS so both the server and client can access it --
local GenericCache = require(game:GetService("ReplicatedStorage").GenericCache)
local testObject = Instance.new("IntValue")
testObject.Value = 10
After completing the previous step, you will want to create a new GenericCache object using GenericCache.new()
with your arguments. Any arguments other than objectConstructor
and objectInput
are optional and will be set to their default values if not passed into the constructor.
- The
objectConstructor
argument must include a function or method at the index “new” unlessobjectInput
is a template Instance - Setting the value of
maxSize
to -1 will result in the cache having an unlimited size
local objectConstructor = Instance
local objectInput = testObject
-- default values for GenericCache Objects --
local initialSize = 0
local maxSize = -1
local resetOnAddition = false
local resetMethodName = "Reset"
local newCache = GenericCache.new(objectConstructor, objectInput, initialSize, maxSize, resetOnAddition, resetMethodName)
Updating Instance Data
Updating GenericCache Instance Data:
There are three methods that can be used to manipulate the instance data of a GenericCache object: :SetMaxSize()
, :SetResetOnAddition()
, and :SetResetMethodName()
. These methods are all quite simple and only require basic arguments.
- The
applyResetMethod
argument will apply the current reset method to all objects in the cache at the time of its method being called (ifresetOnAddition
is also set totrue
). - The default value for applyResetMethod is
false
testCache:SetMaxSize(5)
testCache:SetResetOnAddition(true, false)
testCache:SetResetMethodName("Reset", false)
Checking Cache Contents
Checking the Contents of a GenericCache Object:
Both :ContainsObject()
and any methods beginning with the keyword “return” can be used to check the contents of a GenericCache object without editing it. :ContainsObject()
will search the cache for a specific object, while the return methods will return either the next available object or any objects matching the predicate function passed to them.
- The predicate function must return either
true
orfalse
depending on if the object inputted needs to be returned (true
for removal)
testCache:ContainsObject(testPart)
testCache:ReturnObject()
testCache:ReturnCustomObject(function(object) return true end)
testCache:ReturnCustomObjects(function(object) return true end)
Adding, Removing, and Retrieving Objects
Adding Objects to a GenericCache:
Adding objects to a GenericCache object is very simple and requires either a single object or set of objects to be manually added with either :AddObject()
or :AddObjects
. You can also load a set number of template Instances into the cache with `:LoadObjects().
- Using
:LoadObjects()
will either createobjectCount
copies of the template Instance or callobjectClass.new()
objectCount
times
testCache:AddObject(object)
testCache:AddObjects({objectOne, objectTwo})
testCache:LoadObjects(10)
Removing & Retrieving Objects from a GenericCache
Removing objects from a GenericCache object is just as easy as adding them to it. For removing a specific object, you can use :RemoveObject()
, and for retrieving objects, you can use any of the methods beginning with the keyword “retrieve”. Retrieving a custom set of objects requires a predicate function similar to the methods beginning with “return”.
- All objects that match the predicate function will be removed from the cache and returned
- The predicate function must return either
true
orfalse
depending on if the object needs to be retrieved (true
for removal)
testCache:RemoveObject(object)
testCache:RetrieveObject()
testCache:RetrieveCustomObject(function(object) return true end)
testCache:RetrieveCustomObjects(function(object) return true end)
Clearing, Resetting, and Destroying Caches
Clearing and Destroying GenericCache Objects:
Clearing, resetting, and destroying GenericCache objects is as easy as typing in the method name. :Clear()
clears the cache, :Reset()
resets it, and :Destroy()
destroys it, simple as that.
- Objects stored in the cache will only be GCed if there are no references to them in other code
testCache:Clear()
testCache:Reset()
testCache:Destroy()
Other Info:
I am still working on a more in-depth documentation, but it might be a while until it comes out (I’m lazy), but for now, this post should have everything you need to get started with the module. Feel free to reply with any questions you have, and I will try to answer them as soon as I can.