PySerial's readlines() consumes 25x times as much CPU time as read()

Viewed 383

I'm reading a constant flow of data over a serial port, using pyserial:

import serial
s = serial.Serial('/dev/ttyACM0', 9600)

If I'm using .read method, like this

while True:
    print(s.read(1000))

It consumes something around 1-2% CPU

But if I start getting them in a list, which is more convenient, like that

while True:
    print(s.readlines(1000))

CPU usage suddenly spikes up to 50%, which seems a bit unreasonable with only difference of output being split in the new lines.

Am I doing something wrong, is there a way to get readlines() method to use CPU more sparingly?

Thank you

1 Answers

My guess is that readlines and readline busily poll the serial line for new characters in order to fulfill your request to get a full line (or lines), whereas .read will only read and return when there indeed is new data. You'll probably have to implement buffering and splitting to lines yourself (code untested since I don't have anything on a serial line right now :-) ):

import serial


def read_lines(s, sep=b"\n"):
    buffer = b""
    while True:
        buffer += s.read(1000)
        while sep in buffer:
            line, _, buffer = buffer.partition(sep)
            yield line


s = serial.Serial("/dev/ttyACM0", 9600)

for line in read_lines(s):
    print(line)
Related