- Notifications
You must be signed in to change notification settings - Fork 1k
Performance Issue with Sync and Async Serial Clients with PyModbus 3.8.3 #2561
-
First of all, thank you for maintaining this awesome library! I'm curious if the performance issue between the sync and async serial clients still persists to 3.8.3. I'm reading a battery charger which speaks Modbus and since I'm basing my program off the contributed solar.py example, I'm making around 125-150 separate register calls. That all takes about 12 seconds with the sync client. Based on the documentation, if I'm using the async client, this should be much faster, but I've encountered that the performance is about the same, and actually a bit worse if I'm using the async client. Is that expected? Also, out of curiosity, I've ran the performance.py with the same charger and the result (reading 10 registers with 1, 10, 100, and 1000 loops) between the clients were the same, with the async again performing slightly worse. |
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 3 comments · 3 replies
-
Please add a debug log as pr issue template, your problem is likely that your device does not respond and thus pymodbus tries to reconnect. |
Beta Was this translation helpful? Give feedback.
All reactions
-
Sure, here is the log. The program reads 53 registers in a separate call (i.e. rr1 = read_holding_registers(address1, count1), rr2 = read_holding_registers(address2, count2) vs in a batch, i.e. rr1 = read_holding_registers(address1, count_of_all_registers)). I've also added the tidbit from the client_performance.py file to time how long it takes. This was done using the async client.
Also, to provide a (possibly clearer) example of what I meant separate calls vs batch calls: for addr, format, factor, comment, unit in ( # data_type according to ModbusClientMixin.DATATYPE.value[0] (0, "I", 1, "System Serial Number", "(Num)"), (2, "I", 1, "Program Revision", "(Num)"), (4, "I", 1, "Bootloader Version", "(Num)"),` rr = client.read_holding_registers(address=addr, count=count, slave=1) VS # Assume the total number of registers to be read is 200 rr = client.read_holding_registers(address=addr, count=200, slave=1) |
Beta Was this translation helpful? Give feedback.
All reactions
-
The solar.py example is a user contribution and as far as I know have not been updated for a long time. |
Beta Was this translation helpful? Give feedback.
All reactions
-
Yeah, that's fair. I liked it because it makes writing to log files cleaner, otherwise I'll have to read a lot of registers and then process them separately. It's fine, it's just additional work on my part -- batch reading seems to be working at speed (but I will verify tomorrow). |
Beta Was this translation helpful? Give feedback.
All reactions
-
As you can see from the log:
A read where your devices responds takes 95ms, which is the part that pymodbus do not control (you do partly with bps configuration). Second read is interesting:
beacuse data is split, which must be due to your rs485 converter, because your device sends the message in one go. Anyhow response is still 92 ms. I really cannot see any delay in pymodbus handling, the delay is in the line, your rs485 converter or your device. |
Beta Was this translation helpful? Give feedback.
All reactions
-
That's fair, thank you for the answer! Silly me! I will say though that reading the registers in a batch works. Doing 2 calls of 100 registers finishes in ~450 ms, which is good enough for my needs. Will just have to rework my code :) |
Beta Was this translation helpful? Give feedback.
As you can see from the log:
A read where your devices responds takes 95ms, which is the part that pymodbus do not control (you do partly with bps configuration).
Second read is interesting: