Yeah, this is all correct.
For PAC: I’m not sure why this particular method was chosen in the first place. There’s alternative that I’m looking into, but the original implementers decided not to use it without documenting why. (They’ve long since moved on.)
I didn’t realize the controllers dribbled the responses back until this past winter. :-/
I/O units: due to the layout of the memory map (see Appendix A of the OptoMMP Protocol Guide for details), the chunks of memory we need to read for points are kind of scattered about. There’s not really a straightforward way to avoid small reads, with the possible exception of scratchpad memory.
There are some improvements I could make though, such as always pulling in all digital point states (but that doesn’t help SNAP high density or groov digital modules), or always polling latch and counters along with states (but that means I’ll likely be polling data that isn’t needed), etc.
The memory map makes it straightforward to write a custom client for something, but for general purpose it’s a little cumbersome.
Modbus: this could definitely be improved. I should be combining register ranges as much as possible.
OPC-UA: we rely on the protocol/library we use for hopefully making things efficient. It’s mostly up to the server we’re talking to.
I do most of my testing with groov View running on a 2011 MacBook Pro against a SNAP-PAC-R1.
Edit: Oh, and the PR1 will respond faster than a SNAP-PAC whatever regardless: much faster processor. In my testing, again with groov View running on my laptop, the PR1 response times for a page reading 128 non-contiguous entries out of a large table were roughly 10x lower than the SNAP-PAC-R1.