paulscherrerinstitute / pcaspy

Portable Channel Access Server in Python
BSD 3-Clause "New" or "Revised" License
32 stars 24 forks source link

+Avoid array update notification if value unchanged #69

Closed TheDuz closed 4 years ago

TheDuz commented 4 years ago

This implementation avoid continuous notification of monitored array PVs

xiaoqiangwang commented 4 years ago

I left the array values unchecked for fear of performance overhead for large arrays, e.g. detector image data.

It seems numpy array comparison will go through all elements. On the contrary, list comparison will stop as soon as one element is different. And surprisingly, the comparison between numpy array and list is horrible.

In [28]: a = numpy.arange(5000000)
In [29]: b = 2 * a
In [30]: alist = list(a)
In [31]: blist = list(b)

In [32]: %timeit b != a
100 loops, best of 3: 7.62 ms per loop

In [33]: %timeit blist != alist
The slowest run took 41.91 times longer than the fastest. This could mean that an intermediate result is being cached
10000000 loops, best of 3: 96.7 ns per loop

In [34]: %timeit blist != a
1 loops, best of 3: 422 ms per loop
TheDuz commented 4 years ago

I do understand your concern, but consider that all clients monitoring those large arrays, will trigger a retrasmissions of the whole large array. Consider also that clients may use this change of value notification to trigger actions.

xiaoqiangwang commented 4 years ago

My initial thought was to leave this choice to the user to check if the values are identical and to call setParam or not.

What is your usage of large arrays? In the case of detector image, the data is almost certainly different for each acquisition and checking for difference is redundant.

TheDuz commented 4 years ago

I'm not using large arrays, i just noticed this behavior using https://github.com/kasemir/dbwr. I think that any GUI like CSS will monitor the array variables no?

xiaoqiangwang commented 4 years ago

GUI programs normally put monitors on all PVs. Frequent, identical updates could be a burden for them.

Do you have a user case, where arrays could be updated with identical values?

TheDuz commented 4 years ago

I've deepened the analysis on the problem I'm experiencing. The problem arises when you define a PV with count > 1 and defining a scan rate. i.e.: prefix = 'MTEST:' pvdb = { 'TEST_KO' : { 'count' :2, 'scan' :1, }, 'TEST_OK_1' : { 'count' :3, }, 'TEST_OK_2' : { 'scan' :1, },

executing: camonitor MTEST:TEST_KO

will result in a continuous value update even if no change happens triggered by the setParam inside the scan function.

xiaoqiangwang commented 4 years ago

That is a rather special case. In real world usage, groups of data are normally polled from separate threads and it makes the scan field less useful.

That said, until an efficient comparison can be implemented, I would leave array values unchecked.