Iterating ^$GLOBAL is very slow
I use the following code to loop trough all globals :
set name=""for
{
set name=$order(^$GLOBAL(name))
quit:name=""
write name,!
}However this is really slow : about 1second per node.
I ran debugger, and it seems most of the time is spend in "%SYS.GD Visible" function. There is a comment that says :
"Sees if globals in dataset are visible to our namespace"
This function loop on a global named ^mtemp which contains lot of records (10K or more).
I have cleared global, hoping it has been filled by another process but it's not (it seems to be filled by %SYS.GD)
Why is it so slow, Is there a way to make this faster ?
Comments
^$GLOBAL likely does not cache the list of the globals in the current namespace
So each time you do $Order(^$GLOBAL(name)) it gets the list and looks which global is next after the one in the name. That's fine because globals might appear and disappear between the calls.
If you'd like to loop through the globals -- use merge, and then loop through the temp variable a
merge a = ^$GLOBAL("")
Note, that your loop is much faster if you run it in the database, not namespace, as here ther are no possible mappings to account for
USER>s z1=$zh,n="" f { s n = $O(^$Global(n)) q:n="" } w $zh-z1
3.302887
USER>zn "^^..\user"
...iris\mgr\user\>s z1=$zh,n="" f { s n = $O(^$Global(n)) q:n="" } w $zh-z1
.098734
Thanks for your reply. I didn't know you could run code in database. My guess is that in this context you can only access database globals, not the routines/classes, am I right ?
Depends on which globals are in the database. If you have separate code / data databases for the namespace, then yes -- you'll see only data or only code related globals
Hi Alexander,
before running the second command, and in order to get the right numbers, shouldn't you clear the buffers so system takes it again from the disk?
d ClearBuffers^|"%SYS"|GLOBUFF()
Hi David
Not really! I want to prove that ^$Global is faster from the database directly, so I would benefit from the buffers ;-)
Seriously though -- yes, good point. Even on the second and consequent runs ^$Global from the namespace is noticeably slower, so it uses the same buffers as the ^$Global from the database directly