System.util.globals Performance

Dear All,

I am trying to use system.util.globals as in-memory cache provider because it takes time to get data from Database, the issue I found that it's even running slower than without system.util.globals support.

#cacheProvider = {}
cacheProvider = system.util.globals

def getCache():
	if not GLOBAL_CACHE_ENABLED:
		return None
		
	if cacheProvider.get(CACHE_ROOT_KEY) is None:
		cacheProvider[CACHE_ROOT_KEY] = {}
	
	return cacheProvider.get(CACHE_ROOT_KEY)

Any recommendations what we could use it properly? or any other in-memory cache alternative providers?

Below is description of getGlobals()
system.util.getGlobals | Ignition User Manual (inductiveautomation.com)

Description

This method returns a dictionary that provides access to the legacy global namespace. As of version 7.7.0, most new scripts use the modern style of scoping, which makes the 'global' keyword act very differently. Most importantly, the modern scoping rules mean that variables declared as 'global' are only global within that one module. The system.util.getGlobals() method can be used to interact with older scripts that used the old meaning of the 'global' keyword.

New in 8.1.0

The globals dictionary now persists across the lifetime of the JVM, and is accessible at system.util.globals. This means system.util.globals will work as an alternative to system.util.getGlobals. However, system.util.getGlobals is still the only option that will appear in the Designer's autocomplete feature.

Just having that function getCache will reduce performance.

I recommend restructuring like so:

myCache = system.util.getGlobals().setdefault(CACHE_ROOT_KEY, {})

{ Jython's .setdefault dictionary method is atomic--that is, it is race-free. }

Then wherever you were using getCache() or someScript.getCache(), use myCache or someScript.myCache.

Do be aware that such a cache is itself a memory leak if you have no mechanism to prune old entries, and the resulting memory pressure can make all of Ignition slow.

(Because of the ties to the legacy scripting namespace, I created a more functional and more isolated alternative as system.util.globalVarMap().)

When you say old entries, I assume you mean just removing keys from the globals dict if they're no longer needed?

That, and forcibly pruning least recently used when memory gets tight.

We could remove those ones manually, performance is the key for us, no enhancement made even I use
myCache = system.util.getGlobals().setdefault(CACHE_ROOT_KEY, {})

Any further help would be appreciated.

You'll probably have to share your entire project here to get free help. If you want to pay for formal assistance, contact me privately next week.

Are you sure that it's "get globals" that is causing your performance issues? What else is in the chain? Where does this poor performance come into play?

2 Likes