How important is it to combine system.tag.readBlocking() into a single call?

Hello.

We have some code which, for each machine, reads a tag value, does some math to it, and then writes to another tag. In pseudocode, it looks like this

for machine_name in machine_name_list :
	in_tag_path = "[default]Machines/{0}/Tag_A","[default]Folder/Tag_A".format(machine_name)
	tag_value = system.tag.readBlocking([tag_path])[0].value
	
	other_value = do_complicated_math(tag_value)
	
	out_tag_path = "[default]Machines/{0}/Tag_A","[default]Folder/Tag_B".format(machine_name)
	system.tag.writeBlocking([out_tag_path], other_value)

How large is the weight on the gateway to do all the calls individually, versus building a list of all the tag paths, getting them all at once, iterating through all of them, and then writing them all at once?

Does it matter much if there are "only" 30 tags, or is this more a consideration when you are read/writing thousands of tags at once?

EDIT: I asked this because the search "tag readblocking" didn't seem to return anything pertinent. However "tag readblocking performance" brought up some useful threads:
Strategies for Optimizing Your Ignition System Performance | Inductive Automation
Benchmarking system.tag.readBlocking() performance with 21,000 tags - Ignition - Inductive Automation Forum
It seems like what we're doing is fine to leave as it, but should definitely not be emulated in the future.

It's not "weight on the gateway", it's more like okay, now you're making number of machines * 2 separate requests to the PLC when you could group them all and make just 2.

If these aren't OPC tags then it probably doesn't matter much at all.

1 Like

We are reading from OPC tags, but I was under the impression that OPC tags were caching the data from the OPC server, and system.opc.readValues() would be the one that could cause issues with overloading the OPC server.

The tags we're writing to are memory tags, and this is happening in a gateway script

Oh, you're right there, I overlooked that.

But the writes do happen all the way to the PLC, so you potentially lose some batching there.

(though we do actually attempt to batch writes to OPC tags in the background, it just can't be relied on very easily.)

Meh, carry on then.

Sounds good. The added hassle of having to remember "The item at index 4 corresponds to the machine named XYZ" doesn't seem to be worth the marginal performance benefits

Batching is a big win when there's a network involved. Memory tags + gateway scope = no network.

1 Like

For what it’s worth, you don’t have to remember, you’ll already have a list of tag paths and it’s a simple comprehension to get a dictionary where the tag values can be accessed by name.

I also disagree that there is marginal performance benefits, particularly as the number of tags grows.

If it’s just write and forget, then writeAsync should be used, and then you can probably neglect performance gains, but with blocking calls your blocking the thread 30 times.

I have a library function that takes a list of tagPaths reads them and returns a dictionary, and another which takes that dictionary and the list of tagPaths and writes the values all at once.

There is a reason this advice is echoed all over the forum.

1 Like